public Object invoke(Object target, String methodName, Object[] arguments) {
    if (arguments.length == 0)
      throw new MissingMethodException(METHOD_SIGNATURE, target.getClass(), arguments);

    Map argMap = arguments[0] instanceof Map ? (Map) arguments[0] : Collections.EMPTY_MAP;
    if (argMap.size() == 0) {
      throw new MissingMethodException(METHOD_SIGNATURE, target.getClass(), arguments);
    }

    GrailsWebRequest webRequest =
        (GrailsWebRequest) RequestContextHolder.currentRequestAttributes();

    HttpServletRequest request = webRequest.getCurrentRequest();
    HttpServletResponse response = webRequest.getCurrentResponse();

    if (request.getAttribute(GRAILS_REDIRECT_ISSUED) != null) {
      throw new CannotRedirectException(
          "Cannot issue a redirect(..) here. A previous call to redirect(..) has already redirected the response.");
    }
    if (response.isCommitted()) {
      throw new CannotRedirectException(
          "Cannot issue a redirect(..) here. The response has already been committed either by another redirect or by directly writing to the response.");
    }

    Object actionRef = argMap.get(ARGUMENT_ACTION);
    String controllerName = getControllerName(target, argMap);

    Object id = argMap.get(ARGUMENT_ID);
    String frag =
        argMap.get(ARGUMENT_FRAGMENT) != null ? argMap.get(ARGUMENT_FRAGMENT).toString() : null;
    Object uri = argMap.get(ARGUMENT_URI);
    String url = argMap.containsKey(ARGUMENT_URL) ? argMap.get(ARGUMENT_URL).toString() : null;
    Map params = (Map) argMap.get(ARGUMENT_PARAMS);
    if (params == null) params = new HashMap();
    Errors errors = (Errors) argMap.get(ARGUMENT_ERRORS);
    GroovyObject controller = (GroovyObject) target;

    // if there are errors add it to the list of errors
    Errors controllerErrors =
        (Errors) controller.getProperty(ControllerDynamicMethods.ERRORS_PROPERTY);
    if (controllerErrors != null) {
      controllerErrors.addAllErrors(errors);
    } else {
      controller.setProperty(ControllerDynamicMethods.ERRORS_PROPERTY, errors);
    }

    String actualUri;
    GrailsApplicationAttributes attrs = webRequest.getAttributes();

    if (uri != null) {
      actualUri = attrs.getApplicationUri(request) + uri.toString();
    } else if (url != null) {
      actualUri = url;
    } else {
      String actionName = establishActionName(actionRef, target, webRequest);
      controllerName = controllerName != null ? controllerName : webRequest.getControllerName();

      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "Dynamic method [redirect] looking up URL mapping for controller ["
                + controllerName
                + "] and action ["
                + actionName
                + "] and params ["
                + params
                + "] with ["
                + urlMappingsHolder
                + "]");
      }

      try {
        if (id != null) params.put(ARGUMENT_ID, id);

        UrlCreator urlMapping =
            urlMappingsHolder.getReverseMapping(controllerName, actionName, params);
        if (LOG.isDebugEnabled() && urlMapping == null) {
          LOG.debug("Dynamic method [redirect] no URL mapping found for params [" + params + "]");
        }

        actualUri =
            urlMapping.createURL(
                controllerName, actionName, params, request.getCharacterEncoding(), frag);

        if (LOG.isDebugEnabled()) {
          LOG.debug("Dynamic method [redirect] mapped to URL [" + actualUri + "]");
        }

      } finally {
        if (id != null) params.remove(ARGUMENT_ID);
      }
    }

    return redirectResponse(actualUri, request, response);
  }
Esempio n. 2
0
  public Object invoke(Object target, String methodName, Object[] arguments) {
    if (arguments.length == 0)
      throw new MissingMethodException(METHOD_SIGNATURE, target.getClass(), arguments);

    GrailsWebRequest webRequest =
        (GrailsWebRequest) RequestContextHolder.currentRequestAttributes();
    GrailsApplication application = webRequest.getAttributes().getGrailsApplication();
    HttpServletRequest request = webRequest.getCurrentRequest();
    HttpServletResponse response = webRequest.getCurrentResponse();

    boolean renderView = true;
    GroovyObject controller = (GroovyObject) target;
    if ((arguments[0] instanceof String) || (arguments[0] instanceof GString)) {
      setContentType(response, TEXT_HTML, DEFAULT_ENCODING, true);
      String text = arguments[0].toString();
      renderView = renderText(text, response);
    } else if (arguments[0] instanceof Closure) {
      setContentType(response, TEXT_HTML, gspEncoding, true);
      Closure closure = (Closure) arguments[arguments.length - 1];
      renderView = renderMarkup(closure, response);
    } else if (arguments[0] instanceof Map) {
      Map argMap = (Map) arguments[0];
      Writer out;
      if (argMap.containsKey(ARGUMENT_CONTENT_TYPE) && argMap.containsKey(ARGUMENT_ENCODING)) {
        String contentType = argMap.get(ARGUMENT_CONTENT_TYPE).toString();
        String encoding = argMap.get(ARGUMENT_ENCODING).toString();
        setContentType(response, contentType, encoding);
        out = GSPResponseWriter.getInstance(response, BUFFER_SIZE);
      } else if (argMap.containsKey(ARGUMENT_CONTENT_TYPE)) {
        setContentType(response, argMap.get(ARGUMENT_CONTENT_TYPE).toString(), DEFAULT_ENCODING);
        out = GSPResponseWriter.getInstance(response, BUFFER_SIZE);
      } else {
        setContentType(response, TEXT_HTML, DEFAULT_ENCODING, true);
        out = GSPResponseWriter.getInstance(response, BUFFER_SIZE);
      }

      if (argMap.containsKey(ARGUMENT_STATUS)) {
        Object statusObj = argMap.get(ARGUMENT_STATUS);
        if (statusObj != null) {
          try {
            response.setStatus(Integer.parseInt(statusObj.toString()));
          } catch (NumberFormatException e) {
            throw new ControllerExecutionException(
                "Argument [status] of method [render] must be a valid integer.");
          }
        }
      }

      webRequest.setOut(out);

      if (arguments[arguments.length - 1] instanceof Closure) {
        Closure callable = (Closure) arguments[arguments.length - 1];
        if (BUILDER_TYPE_RICO.equals(argMap.get(ARGUMENT_BUILDER))) {
          renderView = renderRico(callable, response);
        } else if (BUILDER_TYPE_JSON.equals(argMap.get(ARGUMENT_BUILDER))
            || isJSONResponse(response)) {
          renderView = renderJSON(callable, response);
        } else {
          renderView = renderMarkup(callable, response);
        }
      } else if (arguments[arguments.length - 1] instanceof String) {
        String text = (String) arguments[arguments.length - 1];
        renderView = renderText(text, out);
      } else if (argMap.containsKey(ARGUMENT_TEXT)) {
        String text = argMap.get(ARGUMENT_TEXT).toString();
        renderView = renderText(text, out);
      } else if (argMap.containsKey(ARGUMENT_VIEW)) {

        renderView(argMap, target, controller);
      } else if (argMap.containsKey(ARGUMENT_TEMPLATE)) {
        renderView = renderTemplate(target, controller, webRequest, argMap, out);
      } else {
        Object object = arguments[0];
        renderView = renderObject(object, out);
      }
      try {
        if (!renderView) {
          out.flush();
        }
      } catch (IOException e) {
        throw new ControllerExecutionException(
            "I/O error executing render method for arguments [" + argMap + "]: " + e.getMessage(),
            e);
      }
    } else {
      throw new MissingMethodException(METHOD_SIGNATURE, target.getClass(), arguments);
    }
    webRequest.setRenderView(renderView);
    return null;
  }