Exemplo n.º 1
0
  /**
   * @param methodName The name of the function to invoke.
   * @param methodParams A Map, List, or Array of input parameters for the method. Values will be
   *     cast to the appropriate types if necessary.
   */
  private void invokeMethod(String methodName, Object methodParams) throws IOException {
    ServletRequestInfo info = getServletRequestInfo();
    if (!methodMap.containsKey(methodName) || methodMap.get(methodName) == null) {
      sendError(
          new IllegalArgumentException(String.format("Method \"%s\" not supported.", methodName)),
          null);
      return;
    }

    if (methodParams == null) methodParams = new Object[0];

    if (methodParams instanceof Map)
      methodParams = getParamsFromMap(methodName, (Map<?, ?>) methodParams);

    if (methodParams instanceof List<?>) methodParams = ((List<?>) methodParams).toArray();

    if (info.streamParameterIndex != null) {
      int index = info.streamParameterIndex.intValue();
      if (index >= 0) ((Object[]) methodParams)[index] = info.inputStream;
    }

    Object[] params = (Object[]) methodParams;

    // get method by name
    ExposedMethod exposedMethod = methodMap.get(methodName);
    if (exposedMethod == null) {
      sendError(new IllegalArgumentException("Unknown method: " + methodName), null);
      return;
    }

    // cast input values to appropriate types if necessary
    Class<?>[] expectedArgTypes = exposedMethod.method.getParameterTypes();
    if (expectedArgTypes.length == params.length) {
      for (int index = 0; index < params.length; index++) {
        params[index] = cast(params[index], expectedArgTypes[index]);
      }
    }

    // prepare to output the result of the method call
    long startTime = System.currentTimeMillis();

    // Invoke the method on the object with the arguments
    try {
      Object result = exposedMethod.method.invoke(exposedMethod.instance, params);

      if (info.currentJsonRequest == null) // AMF3
      {
        if (exposedMethod.method.getReturnType() != void.class) {
          ServletOutputStream servletOutputStream = info.getOutputStream();
          serializeCompressedAmf3(result, servletOutputStream);
        }
      } else // json
      {
        Object id = info.currentJsonRequest.id;
        /* If ID is empty then it is a notification, we send nothing back */
        if (id != null) {
          JsonRpcResponseModel responseObj = new JsonRpcResponseModel();
          responseObj.jsonrpc = "2.0";
          responseObj.result = result;
          responseObj.id = id;
          info.jsonResponses.add(responseObj);
        }
      }

    } catch (InvocationTargetException e) {
      System.err.println(methodToString(methodName, params));
      sendError(e, null);
    } catch (IllegalArgumentException e) {
      String moreInfo =
          "Expected: "
              + formatFunctionSignature(methodName, expectedArgTypes, exposedMethod.paramNames)
              + "\n"
              + "Received: "
              + formatFunctionSignature(methodName, params, null);

      sendError(e, moreInfo);
    } catch (Exception e) {
      System.err.println(methodToString(methodName, params));
      sendError(e, null);
    }

    long endTime = System.currentTimeMillis();
    // debug
    if (endTime - startTime >= debugThreshold)
      System.out.println(
          String.format("[%sms] %s", endTime - startTime, methodToString(methodName, params)));
  }