Java Code Examples for org.fourthline.cling.model.types.ErrorCode#ARGUMENT_VALUE_INVALID

The following examples show how to use org.fourthline.cling.model.types.ErrorCode#ARGUMENT_VALUE_INVALID . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SOAPActionProcessorImpl.java    From DroidDLNA with GNU General Public License v3.0 6 votes vote down vote up
/**
 * The UPnP spec says that action arguments must be in the order as declared
 * by the service. This method however is lenient, the action argument nodes
 * in the XML can be in any order, as long as they are all there everything
 * is OK.
 */
protected ActionArgumentValue[] readArgumentValues(NodeList nodeList, ActionArgument[] args)
        throws ActionException {

    List<Node> nodes = getMatchingNodes(nodeList, args);

    ActionArgumentValue[] values = new ActionArgumentValue[args.length];

    for (int i = 0; i < args.length; i++) {
    	
        ActionArgument arg = args[i];
        Node node = findActionArgumentNode(nodes, arg);
        if(node == null) {
            throw new ActionException(
                    ErrorCode.ARGUMENT_VALUE_INVALID,
                    "Could not find argument '" + arg.getName() + "' node");
        }
        log.fine("Reading action argument: " + arg.getName());
        String value = XMLUtil.getTextContent(node);
        values[i] = createValue(arg, value);
    }
    return values;
}
 
Example 2
Source File: PullSOAPActionProcessorImpl.java    From TVRemoteIME with GNU General Public License v2.0 6 votes vote down vote up
protected ActionArgumentValue[] readArgumentValues(XmlPullParser xpp, ActionArgument[] args) throws Exception {
    // We're in the <ActionName>Response tag
    Map<String, String> matches = getMatchingNodes(xpp, args);

    ActionArgumentValue[] values = new ActionArgumentValue[args.length];

    for (int i = 0; i < args.length; i++) {

        ActionArgument arg = args[i];
        String value = findActionArgumentValue(matches, arg);
        if (value == null) {
            throw new ActionException(
                ErrorCode.ARGUMENT_VALUE_INVALID,
                "Could not find argument '" + arg.getName() + "' node");
        }

        log.fine("Reading action argument: " + arg.getName());
        values[i] = createValue(arg, value);
    }
    return values;
}
 
Example 3
Source File: SOAPActionProcessorImpl.java    From TVRemoteIME with GNU General Public License v2.0 6 votes vote down vote up
/**
 * The UPnP spec says that action arguments must be in the order as declared
 * by the service. This method however is lenient, the action argument nodes
 * in the XML can be in any order, as long as they are all there everything
 * is OK.
 */
protected ActionArgumentValue[] readArgumentValues(NodeList nodeList, ActionArgument[] args)
        throws ActionException {

    List<Node> nodes = getMatchingNodes(nodeList, args);

    ActionArgumentValue[] values = new ActionArgumentValue[args.length];

    for (int i = 0; i < args.length; i++) {
    	
        ActionArgument arg = args[i];
        Node node = findActionArgumentNode(nodes, arg);
        if(node == null) {
            throw new ActionException(
                    ErrorCode.ARGUMENT_VALUE_INVALID,
                    "Could not find argument '" + arg.getName() + "' node");
        }
        log.fine("Reading action argument: " + arg.getName());
        String value = XMLUtil.getTextContent(node);
        values[i] = createValue(arg, value);
    }
    return values;
}
 
Example 4
Source File: SOAPActionProcessorImpl.java    From TVRemoteIME with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Finds all element nodes in the list that match any argument name or argument
 * alias, throws {@link ActionException} if not all arguments were found.
 */
protected List<Node> getMatchingNodes(NodeList nodeList, ActionArgument[] args) throws ActionException {

    List<String> names = new ArrayList();
    for (ActionArgument argument : args) {
        names.add(argument.getName());
        names.addAll(Arrays.asList(argument.getAliases()));
    }

    List<Node> matches = new ArrayList();
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node child = nodeList.item(i);

        if (child.getNodeType() != Node.ELEMENT_NODE)
            continue;

        if (names.contains(getUnprefixedNodeName(child)))
            matches.add(child);
    }

    if (matches.size() < args.length) {
        throw new ActionException(
                ErrorCode.ARGUMENT_VALUE_INVALID,
                "Invalid number of input or output arguments in XML message, expected " + args.length + " but found " + matches.size()
        );
    }
    return matches;
}
 
Example 5
Source File: PullSOAPActionProcessorImpl.java    From DroidDLNA with GNU General Public License v3.0 5 votes vote down vote up
protected Map<String, String> getMatchingNodes(XmlPullParser xpp, ActionArgument[] args) throws Exception {

        // This is a case-insensitive search!
        List<String> names = new ArrayList<String>();
        for (ActionArgument argument : args) {
            names.add(argument.getName().toUpperCase());
            for (String alias : Arrays.asList(argument.getAliases())) {
                names.add(alias.toUpperCase());
            }
        }

        Map<String, String> matches = new HashMap<String, String>();

        String enclosingTag = xpp.getName();

        int event;
        do {
            event = xpp.next();
            if(event == XmlPullParser.START_TAG && names.contains(xpp.getName().toUpperCase())) {
                matches.put(xpp.getName(), xpp.nextText());
            }

        }
        while (event != XmlPullParser.END_DOCUMENT && (event != XmlPullParser.END_TAG || !xpp.getName().equals(enclosingTag)));

        if (matches.size() < args.length) {
            throw new ActionException(
                ErrorCode.ARGUMENT_VALUE_INVALID,
                "Invalid number of input or output arguments in XML message, expected "
                    + args.length + " but found " + matches.size()
            );
        }
        return matches;
    }
 
Example 6
Source File: SOAPActionProcessorImpl.java    From DroidDLNA with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Creates an instance of {@link ActionArgumentValue} and wraps an
 * {@link InvalidValueException} as an {@link ActionException} with the
 * appropriate {@link ErrorCode}.
 */
protected ActionArgumentValue createValue(ActionArgument arg, String value) throws ActionException {
    try {
        return new ActionArgumentValue(arg, value);
    } catch (InvalidValueException ex) {
        throw new ActionException(
                ErrorCode.ARGUMENT_VALUE_INVALID,
                "Wrong type or invalid value for '" + arg.getName() + "': " + ex.getMessage(),
                ex
        );
    }
}
 
Example 7
Source File: AbstractPeeringConnectionManagerService.java    From DroidDLNA with GNU General Public License v3.0 5 votes vote down vote up
@UpnpAction(out = {
        @UpnpOutputArgument(name = "ConnectionID", stateVariable = "A_ARG_TYPE_ConnectionID", getterName = "getConnectionID"),
        @UpnpOutputArgument(name = "AVTransportID", stateVariable = "A_ARG_TYPE_AVTransportID", getterName = "getAvTransportID"),
        @UpnpOutputArgument(name = "RcsID", stateVariable = "A_ARG_TYPE_RcsID", getterName = "getRcsID")
})
synchronized public ConnectionInfo prepareForConnection(
        @UpnpInputArgument(name = "RemoteProtocolInfo", stateVariable = "A_ARG_TYPE_ProtocolInfo") ProtocolInfo remoteProtocolInfo,
        @UpnpInputArgument(name = "PeerConnectionManager", stateVariable = "A_ARG_TYPE_ConnectionManager") ServiceReference peerConnectionManager,
        @UpnpInputArgument(name = "PeerConnectionID", stateVariable = "A_ARG_TYPE_ConnectionID") int peerConnectionId,
        @UpnpInputArgument(name = "Direction", stateVariable = "A_ARG_TYPE_Direction") String direction)
        throws ActionException {

    int connectionId = getNewConnectionId();

    ConnectionInfo.Direction dir;
    try {
        dir = ConnectionInfo.Direction.valueOf(direction);
    } catch (Exception ex) {
        throw new ConnectionManagerException(ErrorCode.ARGUMENT_VALUE_INVALID, "Unsupported direction: " + direction);
    }

    log.fine("Preparing for connection with local new ID " + connectionId + " and peer connection ID: " + peerConnectionId);

    ConnectionInfo newConnectionInfo = createConnection(
            connectionId,
            peerConnectionId,
            peerConnectionManager,
            dir,
            remoteProtocolInfo
    );

    storeConnection(newConnectionInfo);

    return newConnectionInfo;
}
 
Example 8
Source File: AbstractActionExecutor.java    From DroidDLNA with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Sets the output argument value on the {@link org.fourthline.cling.model.action.ActionInvocation}, considers string conversion.
 */
protected void setOutputArgumentValue(ActionInvocation<LocalService> actionInvocation, ActionArgument<LocalService> argument, Object result)
        throws ActionException {

    LocalService service = actionInvocation.getAction().getService();

    if (result != null) {
        try {
            if (service.isStringConvertibleType(result)) {
                log.fine("Result of invocation matches convertible type, setting toString() single output argument value");
                actionInvocation.setOutput(new ActionArgumentValue(argument, result.toString()));
            } else {
                log.fine("Result of invocation is Object, setting single output argument value");
                actionInvocation.setOutput(new ActionArgumentValue(argument, result));
            }
        } catch (InvalidValueException ex) {
            throw new ActionException(
                    ErrorCode.ARGUMENT_VALUE_INVALID,
                    "Wrong type or invalid value for '" + argument.getName() + "': " + ex.getMessage(),
                    ex
            );
        }
    } else {

        log.fine("Result of invocation is null, not setting any output argument value(s)");
    }

}
 
Example 9
Source File: QueryStateVariableExecutor.java    From DroidDLNA with GNU General Public License v3.0 5 votes vote down vote up
protected void executeQueryStateVariable(ActionInvocation<LocalService> actionInvocation, Object serviceImpl) throws Exception {

        LocalService service = actionInvocation.getAction().getService();

        String stateVariableName = actionInvocation.getInput("varName").toString();
        StateVariable stateVariable = service.getStateVariable(stateVariableName);

        if (stateVariable == null) {
            throw new ActionException(
                    ErrorCode.ARGUMENT_VALUE_INVALID, "No state variable found: " + stateVariableName
            );
        }

        StateVariableAccessor accessor;
        if ((accessor = service.getAccessor(stateVariable.getName())) == null) {
            throw new ActionException(
                    ErrorCode.ARGUMENT_VALUE_INVALID, "No accessor for state variable, can't read state: " + stateVariableName
            );
        }

        try {
            setOutputArgumentValue(
                    actionInvocation,
                    actionInvocation.getAction().getOutputArgument("return"),
                    accessor.read(stateVariable, serviceImpl).toString()
            );
        } catch (Exception ex) {
            throw new ActionException(ErrorCode.ACTION_FAILED, ex.getMessage());
        }
    }
 
Example 10
Source File: QueryStateVariableExecutor.java    From TVRemoteIME with GNU General Public License v2.0 5 votes vote down vote up
protected void executeQueryStateVariable(ActionInvocation<LocalService> actionInvocation, Object serviceImpl) throws Exception {

        LocalService service = actionInvocation.getAction().getService();

        String stateVariableName = actionInvocation.getInput("varName").toString();
        StateVariable stateVariable = service.getStateVariable(stateVariableName);

        if (stateVariable == null) {
            throw new ActionException(
                    ErrorCode.ARGUMENT_VALUE_INVALID, "No state variable found: " + stateVariableName
            );
        }

        StateVariableAccessor accessor;
        if ((accessor = service.getAccessor(stateVariable.getName())) == null) {
            throw new ActionException(
                    ErrorCode.ARGUMENT_VALUE_INVALID, "No accessor for state variable, can't read state: " + stateVariableName
            );
        }

        try {
            setOutputArgumentValue(
                    actionInvocation,
                    actionInvocation.getAction().getOutputArgument("return"),
                    accessor.read(stateVariable, serviceImpl).toString()
            );
        } catch (Exception ex) {
            throw new ActionException(ErrorCode.ACTION_FAILED, ex.getMessage());
        }
    }
 
Example 11
Source File: SOAPActionProcessorImpl.java    From TVRemoteIME with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Creates an instance of {@link ActionArgumentValue} and wraps an
 * {@link InvalidValueException} as an {@link ActionException} with the
 * appropriate {@link ErrorCode}.
 */
protected ActionArgumentValue createValue(ActionArgument arg, String value) throws ActionException {
    try {
        return new ActionArgumentValue(arg, value);
    } catch (InvalidValueException ex) {
        throw new ActionException(
                ErrorCode.ARGUMENT_VALUE_INVALID,
                "Wrong type or invalid value for '" + arg.getName() + "': " + ex.getMessage(),
                ex
        );
    }
}
 
Example 12
Source File: PullSOAPActionProcessorImpl.java    From TVRemoteIME with GNU General Public License v2.0 5 votes vote down vote up
protected Map<String, String> getMatchingNodes(XmlPullParser xpp, ActionArgument[] args) throws Exception {

        // This is a case-insensitive search!
        List<String> names = new ArrayList<String>();
        for (ActionArgument argument : args) {
            names.add(argument.getName().toUpperCase());
            for (String alias : Arrays.asList(argument.getAliases())) {
                names.add(alias.toUpperCase());
            }
        }

        Map<String, String> matches = new HashMap<String, String>();

        String enclosingTag = xpp.getName();

        int event;
        do {
            event = xpp.next();
            if(event == XmlPullParser.START_TAG && names.contains(xpp.getName().toUpperCase())) {
                matches.put(xpp.getName(), xpp.nextText());
            }

        }
        while (event != XmlPullParser.END_DOCUMENT && (event != XmlPullParser.END_TAG || !xpp.getName().equals(enclosingTag)));

        if (matches.size() < args.length) {
            throw new ActionException(
                ErrorCode.ARGUMENT_VALUE_INVALID,
                "Invalid number of input or output arguments in XML message, expected "
                    + args.length + " but found " + matches.size()
            );
        }
        return matches;
    }
 
Example 13
Source File: AbstractAudioRenderingControl.java    From TVRemoteIME with GNU General Public License v2.0 5 votes vote down vote up
protected Channel getChannel(String channelName) throws RenderingControlException {
    try {
        return Channel.valueOf(channelName);
    } catch (IllegalArgumentException ex) {
        throw new RenderingControlException(ErrorCode.ARGUMENT_VALUE_INVALID, "Unsupported audio channel: " + channelName);
    }
}
 
Example 14
Source File: AbstractPeeringConnectionManagerService.java    From TVRemoteIME with GNU General Public License v2.0 5 votes vote down vote up
@UpnpAction(out = {
        @UpnpOutputArgument(name = "ConnectionID", stateVariable = "A_ARG_TYPE_ConnectionID", getterName = "getConnectionID"),
        @UpnpOutputArgument(name = "AVTransportID", stateVariable = "A_ARG_TYPE_AVTransportID", getterName = "getAvTransportID"),
        @UpnpOutputArgument(name = "RcsID", stateVariable = "A_ARG_TYPE_RcsID", getterName = "getRcsID")
})
synchronized public ConnectionInfo prepareForConnection(
        @UpnpInputArgument(name = "RemoteProtocolInfo", stateVariable = "A_ARG_TYPE_ProtocolInfo") ProtocolInfo remoteProtocolInfo,
        @UpnpInputArgument(name = "PeerConnectionManager", stateVariable = "A_ARG_TYPE_ConnectionManager") ServiceReference peerConnectionManager,
        @UpnpInputArgument(name = "PeerConnectionID", stateVariable = "A_ARG_TYPE_ConnectionID") int peerConnectionId,
        @UpnpInputArgument(name = "Direction", stateVariable = "A_ARG_TYPE_Direction") String direction)
        throws ActionException {

    int connectionId = getNewConnectionId();

    ConnectionInfo.Direction dir;
    try {
        dir = ConnectionInfo.Direction.valueOf(direction);
    } catch (Exception ex) {
        throw new ConnectionManagerException(ErrorCode.ARGUMENT_VALUE_INVALID, "Unsupported direction: " + direction);
    }

    log.fine("Preparing for connection with local new ID " + connectionId + " and peer connection ID: " + peerConnectionId);

    ConnectionInfo newConnectionInfo = createConnection(
            connectionId,
            peerConnectionId,
            peerConnectionManager,
            dir,
            remoteProtocolInfo
    );

    storeConnection(newConnectionInfo);

    return newConnectionInfo;
}
 
Example 15
Source File: AbstractActionExecutor.java    From TVRemoteIME with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Sets the output argument value on the {@link org.fourthline.cling.model.action.ActionInvocation}, considers string conversion.
 */
protected void setOutputArgumentValue(ActionInvocation<LocalService> actionInvocation, ActionArgument<LocalService> argument, Object result)
        throws ActionException {

    LocalService service = actionInvocation.getAction().getService();

    if (result != null) {
        try {
            if (service.isStringConvertibleType(result)) {
                log.fine("Result of invocation matches convertible type, setting toString() single output argument value");
                actionInvocation.setOutput(new ActionArgumentValue(argument, result.toString()));
            } else {
                log.fine("Result of invocation is Object, setting single output argument value");
                actionInvocation.setOutput(new ActionArgumentValue(argument, result));
            }
        } catch (InvalidValueException ex) {
            throw new ActionException(
                    ErrorCode.ARGUMENT_VALUE_INVALID,
                    "Wrong type or invalid value for '" + argument.getName() + "': " + ex.getMessage(),
                    ex
            );
        }
    } else {

        log.fine("Result of invocation is null, not setting any output argument value(s)");
    }

}
 
Example 16
Source File: SOAPActionProcessorImpl.java    From DroidDLNA with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Finds all element nodes in the list that match any argument name or argument
 * alias, throws {@link ActionException} if not all arguments were found.
 */
protected List<Node> getMatchingNodes(NodeList nodeList, ActionArgument[] args) throws ActionException {

    List<String> names = new ArrayList();
    for (ActionArgument argument : args) {
        names.add(argument.getName());
        names.addAll(Arrays.asList(argument.getAliases()));
    }

    List<Node> matches = new ArrayList();
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node child = nodeList.item(i);

        if (child.getNodeType() != Node.ELEMENT_NODE)
            continue;

        if (names.contains(getUnprefixedNodeName(child)))
            matches.add(child);
    }

    if (matches.size() < args.length) {
        throw new ActionException(
                ErrorCode.ARGUMENT_VALUE_INVALID,
                "Invalid number of input or output arguments in XML message, expected " + args.length + " but found " + matches.size()
        );
    }
    return matches;
}
 
Example 17
Source File: AudioRenderingControl.java    From TVRemoteIME with GNU General Public License v2.0 4 votes vote down vote up
protected void checkChannel(String channelName) throws RenderingControlException {
    if (!getChannel(channelName).equals(Channel.Master)) {
        throw new RenderingControlException(ErrorCode.ARGUMENT_VALUE_INVALID, "Unsupported audio channel: " + channelName);
    }
}
 
Example 18
Source File: AudioRenderingControl.java    From DroidDLNA with GNU General Public License v3.0 4 votes vote down vote up
protected void checkChannel(String channelName) throws RenderingControlException {
    if (!getChannel(channelName).equals(Channel.Master)) {
        throw new RenderingControlException(ErrorCode.ARGUMENT_VALUE_INVALID, "Unsupported audio channel: " + channelName);
    }
}
 
Example 19
Source File: MethodActionExecutor.java    From DroidDLNA with GNU General Public License v3.0 4 votes vote down vote up
protected Object[] createInputArgumentValues(ActionInvocation<LocalService> actionInvocation, Method method) throws ActionException {

        LocalService service = actionInvocation.getAction().getService();

        List values = new ArrayList();
        int i = 0;
        for (ActionArgument<LocalService> argument : actionInvocation.getAction().getInputArguments()) {

            Class methodParameterType = method.getParameterTypes()[i];

            ActionArgumentValue<LocalService> inputValue = actionInvocation.getInput(argument);

            // If it's a primitive argument, we need a value
            if (methodParameterType.isPrimitive() && (inputValue == null || inputValue.toString().length() == 0))
                throw new ActionException(
                        ErrorCode.ARGUMENT_VALUE_INVALID,
                        "Primitive action method argument '" + argument.getName() + "' requires input value, can't be null or empty string"
                );

            // It's not primitive and we have no value, that's fine too
            if (inputValue == null) {
                values.add(i++, null);
                continue;
            }

            // If it's not null, maybe it was a string-convertible type, if so, try to instantiate it
            String inputCallValueString = inputValue.toString();
            // Empty string means null and we can't instantiate Enums!
            if (inputCallValueString.length() > 0 && service.isStringConvertibleType(methodParameterType) && !methodParameterType.isEnum()) {
                try {
                    Constructor<String> ctor = methodParameterType.getConstructor(String.class);
                    log.finer("Creating new input argument value instance with String.class constructor of type: " + methodParameterType);
                    Object o = ctor.newInstance(inputCallValueString);
                    values.add(i++, o);
                } catch (Exception ex) {
                    log.warning("Error preparing action method call: " + method);
                    log.warning("Can't convert input argument string to desired type of '" + argument.getName() + "': " + ex);
                    throw new ActionException(
                            ErrorCode.ARGUMENT_VALUE_INVALID, "Can't convert input argument string to desired type of '" + argument.getName() + "': " + ex
                    );
                }
            } else {
                // Or if it wasn't, just use the value without any conversion
                values.add(i++, inputValue.getValue());
            }
        }

        if (method.getParameterTypes().length > 0
            && RemoteClientInfo.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length-1])) {
            if (actionInvocation instanceof RemoteActionInvocation &&
                ((RemoteActionInvocation)actionInvocation).getRemoteClientInfo() != null) {
                log.finer("Providing remote client info as last action method input argument: " + method);
                values.add(i, ((RemoteActionInvocation)actionInvocation).getRemoteClientInfo());
            } else {
                // Local call, no client info available
                values.add(i, null);
            }
        }

        return values.toArray(new Object[values.size()]);
    }
 
Example 20
Source File: MethodActionExecutor.java    From TVRemoteIME with GNU General Public License v2.0 4 votes vote down vote up
protected Object[] createInputArgumentValues(ActionInvocation<LocalService> actionInvocation, Method method) throws ActionException {

        LocalService service = actionInvocation.getAction().getService();

        List values = new ArrayList();
        int i = 0;
        for (ActionArgument<LocalService> argument : actionInvocation.getAction().getInputArguments()) {

            Class methodParameterType = method.getParameterTypes()[i];

            ActionArgumentValue<LocalService> inputValue = actionInvocation.getInput(argument);

            // If it's a primitive argument, we need a value
            if (methodParameterType.isPrimitive() && (inputValue == null || inputValue.toString().length() == 0))
                throw new ActionException(
                        ErrorCode.ARGUMENT_VALUE_INVALID,
                        "Primitive action method argument '" + argument.getName() + "' requires input value, can't be null or empty string"
                );

            // It's not primitive and we have no value, that's fine too
            if (inputValue == null) {
                values.add(i++, null);
                continue;
            }

            // If it's not null, maybe it was a string-convertible type, if so, try to instantiate it
            String inputCallValueString = inputValue.toString();
            // Empty string means null and we can't instantiate Enums!
            if (inputCallValueString.length() > 0 && service.isStringConvertibleType(methodParameterType) && !methodParameterType.isEnum()) {
                try {
                    Constructor<String> ctor = methodParameterType.getConstructor(String.class);
                    log.finer("Creating new input argument value instance with String.class constructor of type: " + methodParameterType);
                    Object o = ctor.newInstance(inputCallValueString);
                    values.add(i++, o);
                } catch (Exception ex) {
                    log.warning("Error preparing action method call: " + method);
                    log.warning("Can't convert input argument string to desired type of '" + argument.getName() + "': " + ex);
                    throw new ActionException(
                            ErrorCode.ARGUMENT_VALUE_INVALID, "Can't convert input argument string to desired type of '" + argument.getName() + "': " + ex
                    );
                }
            } else {
                // Or if it wasn't, just use the value without any conversion
                values.add(i++, inputValue.getValue());
            }
        }

        if (method.getParameterTypes().length > 0
            && RemoteClientInfo.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length-1])) {
            if (actionInvocation instanceof RemoteActionInvocation &&
                ((RemoteActionInvocation)actionInvocation).getRemoteClientInfo() != null) {
                log.finer("Providing remote client info as last action method input argument: " + method);
                values.add(i, ((RemoteActionInvocation)actionInvocation).getRemoteClientInfo());
            } else {
                // Local call, no client info available
                values.add(i, null);
            }
        }

        return values.toArray(new Object[values.size()]);
    }