public void testDecoratedByApplicationConvention() throws Exception {
    GrailsWebRequest webRequest = buildMockRequest();
    MockApplicationContext appCtx = (MockApplicationContext) webRequest.getApplicationContext();
    appCtx.registerMockResource(
        "WEB-INF/grails-app/views/layouts/application.gsp",
        "<html><body><h1>Default Layout</h1><g:layoutBody /></body></html>");

    MockHttpServletRequest request = new MockHttpServletRequest("GET", "orders/list");
    ServletContext context = webRequest.getServletContext();
    GroovyClassLoader gcl = new GroovyClassLoader();

    // create mock controller
    GroovyObject controller =
        (GroovyObject)
            gcl.parseClass(
                    "class FooController {\n"
                        + "def controllerName = 'foo'\n"
                        + "def actionUri = '/foo/fooAction'\n"
                        + "}")
                .newInstance();

    request.setAttribute(GrailsApplicationAttributes.CONTROLLER, controller);
    GrailsLayoutDecoratorMapper m = new GrailsLayoutDecoratorMapper();
    Config c = new Config(new MockServletConfig(context));
    m.init(c, null, null);
    HTMLPageParser parser = new HTMLPageParser();
    String html = "<html><head><title>Foo title</title></head><body>here is the body</body></html>";

    Page page = parser.parse(html.toCharArray());
    Decorator d = m.getDecorator(request, page);
    assertNotNull(d);
    assertEquals("/WEB-INF/grails-app/views/layouts/application.gsp", d.getPage());
    assertEquals("application", d.getName());
  }
  private static GrailsDomainClass getDomainClass(Object instance) {
    GrailsDomainClass domainClass =
        GrailsMetaClassUtils.getPropertyIfExists(
            instance, GrailsDomainClassProperty.DOMAIN_CLASS, GrailsDomainClass.class);
    if (domainClass == null) {
      GrailsWebRequest webRequest = GrailsWebRequest.lookup();
      if (webRequest != null) {
        ApplicationContext applicationContext = webRequest.getApplicationContext();

        GrailsApplication grailsApplication =
            applicationContext.containsBean(GrailsApplication.APPLICATION_ID)
                ? applicationContext.getBean(
                    GrailsApplication.APPLICATION_ID, GrailsApplication.class)
                : null;
        if (grailsApplication != null) {
          domainClass =
              (GrailsDomainClass)
                  grailsApplication.getArtefact(
                      DomainClassArtefactHandler.TYPE, instance.getClass().getName());
        }
      }
    }

    return domainClass;
  }
  @Override
  protected View createFallbackView(String viewName) throws Exception {
    GrailsWebRequest webRequest = GrailsWebRequest.lookup();

    String[] viewNameParts = splitViewName(viewName);
    if (viewNameParts.length == 1) {
      viewName = WebUtils.addViewPrefix(viewName, webRequest.getControllerName());
      viewNameParts = splitViewName(viewName);
    }

    View v = scaffoldedViews.get(viewName);
    if (v == null) {
      GrailsDomainClass domainClass = scaffoldedDomains.get(viewNameParts[0]);
      if (domainClass != null) {
        String viewCode = null;
        try {
          viewCode = generateViewSource(viewNameParts[1], domainClass);
        } catch (Exception e) {
          log.error("Error generating scaffolded view [" + viewName + "]: " + e.getMessage(), e);
        }
        if (StringUtils.hasLength(viewCode)) {
          v = createScaffoldedView(viewName, viewCode);
          scaffoldedViews.put(viewName, v);
        }
      }
    }
    if (v != null) {
      return v;
    }
    return super.createFallbackView(viewName);
  }
Example #4
0
 private static GroovyObject lookupCachedTagLib(
     GrailsWebRequest webRequest,
     TagLibraryLookup gspTagLibraryLookup,
     String namespace,
     String tagName) {
   if (webRequest != null) {
     // caches the taglibs in request context. is this a good idea or not?
     String tagKey = namespace + ":" + tagName;
     Map<String, GroovyObject> tagLibCache =
         (Map<String, GroovyObject>)
             webRequest.getCurrentRequest().getAttribute(REQUEST_TAGLIB_CACHE);
     GroovyObject tagLib = null;
     if (tagLibCache == null) {
       tagLibCache = new HashMap<String, GroovyObject>();
       webRequest.getCurrentRequest().setAttribute(REQUEST_TAGLIB_CACHE, tagLibCache);
     } else {
       tagLib = tagLibCache.get(tagKey);
     }
     if (tagLib == null) {
       tagLib = gspTagLibraryLookup.lookupTagLibrary(namespace, tagName);
       if (tagLib != null) {
         tagLibCache.put(tagKey, tagLib);
       }
     }
     return tagLib;
   } else {
     return gspTagLibraryLookup != null
         ? gspTagLibraryLookup.lookupTagLibrary(namespace, tagName)
         : null;
   }
 }
  protected Object findArg(HttpServletRequest request, Class<?> type, String name) {

    if (String.class.equals(type)) {
      return request.getParameter(name);
    }

    if (PRIMITIVE_CLASSES.contains(type) || TYPE_TO_CONVERSION_METHOD_NAME.containsKey(type)) {

      String conversionMethodName;
      if (TYPE_TO_CONVERSION_METHOD_NAME.containsKey(type)) {
        conversionMethodName = TYPE_TO_CONVERSION_METHOD_NAME.get(type);
      } else {
        conversionMethodName = type.getName();
      }

      GrailsWebRequest grailsRequest =
          (GrailsWebRequest) RequestContextHolder.getRequestAttributes();
      GrailsParameterMap params = grailsRequest.getParams();

      return getParamValue(params, conversionMethodName, name);
    }

    log.warn("Unsupported parameter type " + type + " for parameter " + name);
    return null;
  }
  private View createGrailsView(String viewName) throws Exception {
    // try GSP if res is null

    GrailsWebRequest webRequest = WebUtils.retrieveGrailsWebRequest();

    HttpServletRequest request = webRequest.getCurrentRequest();
    GroovyObject controller = webRequest.getAttributes().getController(request);

    if (grailsApplication == null) {

      grailsApplication =
          getApplicationContext()
              .getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class);
    }

    ResourceLoader loader = establishResourceLoader(grailsApplication);

    String format =
        request.getAttribute(GrailsApplicationAttributes.CONTENT_FORMAT) != null
            ? request.getAttribute(GrailsApplicationAttributes.CONTENT_FORMAT).toString()
            : null;
    String gspView = localPrefix + viewName + DOT + format + GSP_SUFFIX;
    Resource res = null;

    if (format != null) {
      res = loader.getResource(gspView);
      if (!res.exists()) {
        View v = lookupBinaryPluginView(webRequest, controller, gspView);
        if (v != null) {
          return v;
        }
        gspView = resolveViewForController(controller, grailsApplication, viewName, loader);
        res = loader.getResource(gspView);
      }
    }

    if (res == null || !res.exists()) {
      gspView = localPrefix + viewName + GSP_SUFFIX;
      res = loader.getResource(gspView);
      if (!res.exists()) {
        View v = lookupBinaryPluginView(webRequest, controller, gspView);
        if (v != null) {
          return v;
        }
        gspView = resolveViewForController(controller, grailsApplication, viewName, loader);
        res = loader.getResource(gspView);
      }
    }

    if (res.exists()) {
      return createGroovyPageView(webRequest, gspView);
    }

    AbstractUrlBasedView view = buildView(viewName);
    view.setApplicationContext(getApplicationContext());
    view.afterPropertiesSet();
    return view;
  }
 protected void copyParamsFromPreviousRequest(
     GrailsWebRequest previousRequestAttributes, GrailsWebRequest requestAttributes) {
   Map previousParams = previousRequestAttributes.getParams();
   Map params = requestAttributes.getParams();
   for (Iterator i = previousParams.keySet().iterator(); i.hasNext(); ) {
     String name = (String) i.next();
     params.put(name, previousParams.get(name));
   }
 }
 /**
  * Binds a Mock implementation of a GrailsWebRequest object to the current thread. The mock
  * version uses instances of the Spring MockHttpServletRequest, MockHttpServletResponse and
  * MockServletContext classes.
  *
  * @param ctx The WebApplicationContext to use
  * @see org.springframework.mock.web.MockHttpServletRequest
  * @see org.springframework.mock.web.MockHttpServletResponse
  * @see org.springframework.mock.web.MockServletContext
  * @return The GrailsWebRequest instance
  */
 public static GrailsWebRequest bindMockWebRequest(WebApplicationContext ctx) {
   MockHttpServletRequest request = new MockHttpServletRequest();
   GrailsWebRequest webRequest =
       new GrailsWebRequest(request, new MockHttpServletResponse(), ctx.getServletContext());
   request.setAttribute(GrailsApplicationAttributes.WEB_REQUEST, webRequest);
   String[] paramListenerBeans = ctx.getBeanNamesForType(ParameterCreationListener.class);
   for (String paramListenerBean : paramListenerBeans) {
     ParameterCreationListener creationListenerBean =
         (ParameterCreationListener) ctx.getBean(paramListenerBean);
     webRequest.addParameterListener(creationListenerBean);
   }
   RequestContextHolder.setRequestAttributes(webRequest);
   return webRequest;
 }
  private boolean renderTemplate(
      Object target, GroovyObject controller, GrailsWebRequest webRequest, Map argMap, Writer out) {
    boolean renderView;
    String templateName = argMap.get(ARGUMENT_TEMPLATE).toString();
    String contextPath = getContextPath(webRequest, argMap);

    String var = (String) argMap.get(ARGUMENT_VAR);
    // get the template uri
    String templateUri = GroovyPageUtils.getTemplateURI(controller, templateName);

    // retrieve gsp engine
    GroovyPagesTemplateEngine engine =
        (GroovyPagesTemplateEngine)
            webRequest.getApplicationContext().getBean(GroovyPagesTemplateEngine.BEAN_ID);
    try {
      Resource r = engine.getResourceForUri(contextPath + templateUri);
      if (!r.exists()) {
        r = engine.getResourceForUri(contextPath + "/grails-app/views/" + templateUri);
      }

      Template t = engine.createTemplate(r); // templateUri);

      if (t == null) {
        throw new ControllerExecutionException(
            "Unable to load template for uri [" + templateUri + "]. Template not found.");
      }
      Map binding = new HashMap();

      if (argMap.containsKey(ARGUMENT_BEAN)) {
        Object bean = argMap.get(ARGUMENT_BEAN);
        if (argMap.containsKey(ARGUMENT_MODEL)) {
          Object modelObject = argMap.get(ARGUMENT_MODEL);
          if (modelObject instanceof Map) binding.putAll((Map) modelObject);
        }
        renderTemplateForBean(t, binding, bean, var, out);
      } else if (argMap.containsKey(ARGUMENT_COLLECTION)) {
        Object colObject = argMap.get(ARGUMENT_COLLECTION);
        if (argMap.containsKey(ARGUMENT_MODEL)) {
          Object modelObject = argMap.get(ARGUMENT_MODEL);
          if (modelObject instanceof Map) binding.putAll((Map) modelObject);
        }
        renderTemplateForCollection(t, binding, colObject, var, out);
      } else if (argMap.containsKey(ARGUMENT_MODEL)) {
        Object modelObject = argMap.get(ARGUMENT_MODEL);
        renderTemplateForModel(t, modelObject, target, out);
      } else {
        Writable w = t.make(new BeanMap(target));
        w.writeTo(out);
      }
      renderView = false;
    } catch (GroovyRuntimeException gre) {
      throw new ControllerExecutionException(
          "Error rendering template [" + templateName + "]: " + gre.getMessage(), gre);
    } catch (IOException ioex) {
      throw new ControllerExecutionException(
          "I/O error executing render method for arguments [" + argMap + "]: " + ioex.getMessage(),
          ioex);
    }
    return renderView;
  }
 private View createGroovyPageView(GrailsWebRequest webRequest, String gspView) {
   if (LOG.isDebugEnabled()) {
     LOG.debug("Resolved GSP view at URI [" + gspView + "]");
   }
   GroovyPageView gspSpringView = new GroovyPageView();
   gspSpringView.setServletContext(webRequest.getServletContext());
   gspSpringView.setUrl(gspView);
   gspSpringView.setApplicationContext(getApplicationContext());
   gspSpringView.setTemplateEngine(templateEngine);
   return gspSpringView;
 }
  /**
   * Creates a Template for the given Spring Resource instance
   *
   * @param resource The Resource to create the Template for
   * @return The Template instance
   */
  public Template createTemplate(Resource resource) {
    if (resource == null) {
      GrailsWebRequest webRequest = getWebRequest();
      throw new GroovyPagesException(
          "No Groovy page found for URI: " + getCurrentRequestUri(webRequest.getCurrentRequest()));
    }
    String name = establishPageName(resource, null);

    if (!isReloadEnabled()) {
      // presumably war deployed mode, but precompiled gsp isn't used, log this for debugging
      if (LOG.isDebugEnabled()) {
        LOG.debug(
            "Creating template using resource " + resource,
            new Exception("Creating template using resource " + resource));
      } else if (LOG.isInfoEnabled()) {
        LOG.info("Creating template using resource " + resource);
      }
    }

    if (pageCache.containsKey(name)) {
      GroovyPageMetaInfo meta = pageCache.get(name);

      if (isGroovyPageReloadable(resource, meta)) {
        try {
          return createTemplateWithResource(resource);
        } catch (IOException e) {
          throw new GroovyPagesException(
              "I/O error reading stream for resource [" + resource + "]: " + e.getMessage(), e);
        }
      } else {
        return new GroovyPageTemplate(meta);
      }
    } else {
      try {
        return createTemplateWithResource(resource);
      } catch (IOException e) {
        throw new GroovyPagesException(
            "I/O error reading stream for resource [" + resource + "]: " + e.getMessage(), e);
      }
    }
  }
  /*
   * Test method for 'org.codehaus.groovy.grails.web.sitemesh.GrailsLayoutDecoratorMapper.getDecorator(HttpServletRequest, Page)'
   */
  public void testGetDecoratorHttpServletRequestPage() throws Exception {
    GrailsWebRequest webRequest = buildMockRequest();
    MockApplicationContext appCtx = (MockApplicationContext) webRequest.getApplicationContext();
    appCtx.registerMockResource(
        "WEB-INF/grails-app/views/layouts/test.gsp", "<html><body><g:layoutBody /></body></html>");

    MockHttpServletRequest request = new MockHttpServletRequest("GET", "orders/list");
    ServletContext context = webRequest.getServletContext();
    GrailsLayoutDecoratorMapper m = new GrailsLayoutDecoratorMapper();
    Config c = new Config(new MockServletConfig(context));
    m.init(c, null, null);
    HTMLPageParser parser = new HTMLPageParser();
    String html =
        "<html><head><title>Test title</title><meta name=\"layout\" content=\"test\"></meta></head><body>here is the body</body></html>";

    Page page = parser.parse(html.toCharArray());
    Decorator d = m.getDecorator(request, page);
    assertNotNull(d);
    assertEquals("/WEB-INF/grails-app/views/layouts/test.gsp", d.getPage());
    assertEquals("test", d.getName());
  }
Example #13
0
  private void bindWithRequestAndPropertyValues(
      ServletRequest request, MutablePropertyValues mpvs) {
    GrailsWebRequest webRequest = GrailsWebRequest.lookup((HttpServletRequest) request);
    if (webRequest != null) {
      final ApplicationContext applicationContext = webRequest.getApplicationContext();
      if (applicationContext != null) {
        final Map<String, BindEventListener> bindEventListenerMap =
            applicationContext.getBeansOfType(BindEventListener.class);
        for (BindEventListener bindEventListener : bindEventListenerMap.values()) {
          bindEventListener.doBind(getTarget(), mpvs, getTypeConverter());
        }
      }
    }
    preProcessMutablePropertyValues(mpvs);

    if (request instanceof MultipartHttpServletRequest) {
      MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
      bindMultipartFiles(multipartRequest.getFileMap(), mpvs);
    }
    doBind(mpvs);
  }
  @Override
  protected View loadView(String viewName, Locale locale) throws Exception {
    final View resolvedView = super.loadView(viewName, locale);
    if (templateGenerator == null || resolvedView instanceof GroovyPageView) {
      return resolvedView;
    }

    GrailsWebRequest webRequest = WebUtils.retrieveGrailsWebRequest();
    List<String> controllerActions = scaffoldedActionMap.get(webRequest.getControllerName());
    if (controllerActions != null && controllerActions.contains(webRequest.getActionName())) {
      GrailsDomainClass domainClass = scaffoldedDomains.get(webRequest.getControllerName());
      if (domainClass != null) {
        String viewFileName;
        final int i = viewName.lastIndexOf('/');
        if (i > -1) {
          viewFileName = viewName.substring(i, viewName.length());
        } else {
          viewFileName = viewName;
        }
        final ViewKey viewKey = new ViewKey(webRequest.getControllerName(), viewFileName);
        View v = scaffoldedViews.get(viewKey);
        if (v == null) {
          String viewCode = null;
          try {
            viewCode = generateViewSource(webRequest, domainClass);
          } catch (Exception e) {
            GrailsUtil.deepSanitize(e);
            LOG.error("Error generating scaffolded view [" + viewName + "]: " + e.getMessage(), e);
            return resolvedView;
          }
          v = createScaffoldedView(viewName, viewCode);
          scaffoldedViews.put(viewKey, v);
        }
        if (v != null) {
          return v;
        }
      }
    }
    return resolvedView;
  }
Example #15
0
  private String getContextPath(GrailsWebRequest webRequest, Map argMap) {
    Object cp = argMap.get(ARGUMENT_CONTEXTPATH);
    String contextPath = (cp != null ? cp.toString() : "");

    Object pluginName = argMap.get(ARGUMENT_PLUGIN);
    if (pluginName != null) {
      ApplicationContext applicationContext = webRequest.getApplicationContext();
      GrailsPluginManager pluginManager =
          (GrailsPluginManager) applicationContext.getBean(GrailsPluginManager.BEAN_NAME);
      GrailsPlugin plugin = pluginManager.getGrailsPlugin(pluginName.toString());
      if (plugin != null && !plugin.isBasePlugin()) contextPath = plugin.getPluginPath();
    }
    return contextPath;
  }
  @SuppressWarnings({"unchecked", "rawtypes"})
  protected void copyParamsFromPreviousRequest(
      RequestAttributes previousRequestAttributes, GrailsWebRequest requestAttributes) {
    if (!(previousRequestAttributes instanceof GrailsWebRequest)) {
      return;
    }

    Map previousParams = ((GrailsWebRequest) previousRequestAttributes).getParams();
    Map params = requestAttributes.getParams();
    for (Object o : previousParams.keySet()) {
      String name = (String) o;
      params.put(name, previousParams.get(name));
    }
  }
  /**
   * Populates request parameters for the given UrlMappingInfo instance using the GrailsWebRequest
   *
   * @param webRequest The Map instance
   * @see org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest
   */
  @SuppressWarnings("unchecked")
  protected void populateParamsForMapping(GrailsWebRequest webRequest) {
    Map dispatchParams = webRequest.getParams();
    String encoding = webRequest.getRequest().getCharacterEncoding();
    if (encoding == null) encoding = "UTF-8";

    for (Map.Entry<String, Object> entry : params.entrySet()) {
      String name = entry.getKey();
      Object param = entry.getValue();
      if (param instanceof Closure) {
        param = evaluateNameForValue(param);
      }
      if (param instanceof String) {
        try {
          param = URLDecoder.decode((String) param, encoding);
        } catch (UnsupportedEncodingException e) {
          param = evaluateNameForValue(param);
        }
      }
      dispatchParams.put(name, param);
    }

    final String viewName = getViewName();
    if (viewName == null && getURI() == null) {
      webRequest.setControllerName(getControllerName());
      webRequest.setActionName(getActionName());
    }

    String id = getId();
    if (!StringUtils.isBlank(id))
      try {
        dispatchParams.put(GrailsWebRequest.ID_PARAMETER, URLDecoder.decode(id, encoding));
      } catch (UnsupportedEncodingException e) {
        dispatchParams.put(GrailsWebRequest.ID_PARAMETER, id);
      }
  }
  public void testDecoratedByApplicationConventionForViewsNotRenderedByAController()
      throws Exception {
    GrailsWebRequest webRequest = buildMockRequest();
    MockApplicationContext appCtx = (MockApplicationContext) webRequest.getApplicationContext();
    appCtx.registerMockResource(
        "WEB-INF/grails-app/views/layouts/application.gsp",
        "<html><body><h1>Default Layout</h1><g:layoutBody /></body></html>");

    MockHttpServletRequest request = new MockHttpServletRequest("GET", "/");
    ServletContext context = webRequest.getServletContext();
    GroovyClassLoader gcl = new GroovyClassLoader();

    GrailsLayoutDecoratorMapper m = new GrailsLayoutDecoratorMapper();
    Config c = new Config(new MockServletConfig(context));
    m.init(c, null, null);
    HTMLPageParser parser = new HTMLPageParser();
    String html = "<html><head><title>Foo title</title></head><body>here is the body</body></html>";

    Page page = parser.parse(html.toCharArray());
    Decorator d = m.getDecorator(request, page);
    assertNotNull(d);
    assertEquals("/WEB-INF/grails-app/views/layouts/application.gsp", d.getPage());
    assertEquals("application", d.getName());
  }
  protected String evaluateNameForValue(Object value, GrailsWebRequest webRequest) {
    if (value == null) {
      return null;
    }

    String name;
    if (value instanceof Closure) {
      Closure callable = (Closure) value;
      final Closure cloned = (Closure) callable.clone();
      cloned.setDelegate(webRequest);
      cloned.setResolveStrategy(Closure.DELEGATE_FIRST);
      Object result = cloned.call();
      name = result != null ? result.toString() : null;
    } else if (value instanceof Map) {
      Map httpMethods = (Map) value;
      name = (String) httpMethods.get(webRequest.getCurrentRequest().getMethod());
    } else {
      name = value.toString();
    }
    return name != null ? name.trim() : null;
  }
 protected String generateViewSource(GrailsWebRequest webRequest, GrailsDomainClass domainClass) {
   StringWriter sw = new StringWriter();
   templateGenerator.generateView(domainClass, webRequest.getActionName(), sw);
   return sw.toString();
 }
  /* (non-Javadoc)
   * @see org.springframework.web.servlet.DispatcherServlet#doDispatch(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
   */
  protected void doDispatch(final HttpServletRequest request, HttpServletResponse response)
      throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    int interceptorIndex = -1;
    final LocaleResolver localeResolver =
        (LocaleResolver) request.getAttribute(LOCALE_RESOLVER_ATTRIBUTE);

    // Expose current LocaleResolver and request as LocaleContext.
    LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
    LocaleContextHolder.setLocaleContext(
        new LocaleContext() {
          public Locale getLocale() {

            return localeResolver.resolveLocale(request);
          }
        });

    // If the request is an include we need to try to use the original wrapped sitemesh
    // response, otherwise layouts won't work properly
    if (WebUtils.isIncludeRequest(request)) {
      response = useWrappedOrOriginalResponse(response);
    }

    GrailsWebRequest requestAttributes = null;
    GrailsWebRequest previousRequestAttributes = null;
    Exception handlerException = null;
    try {
      ModelAndView mv = null;
      try {
        Object exceptionAttribute = request.getAttribute(EXCEPTION_ATTRIBUTE);
        // only process multipart requests if an exception hasn't occured
        if (exceptionAttribute == null) processedRequest = checkMultipart(request);
        // Expose current RequestAttributes to current thread.
        previousRequestAttributes =
            (GrailsWebRequest) RequestContextHolder.currentRequestAttributes();
        requestAttributes = new GrailsWebRequest(processedRequest, response, getServletContext());
        copyParamsFromPreviousRequest(previousRequestAttributes, requestAttributes);

        // Update the current web request.
        WebUtils.storeGrailsWebRequest(requestAttributes);

        if (logger.isDebugEnabled()) {
          logger.debug("Bound request context to thread: " + request);
          logger.debug("Using response object: " + response.getClass());
        }

        // Determine handler for the current request.
        mappedHandler = getHandler(processedRequest, false);
        if (mappedHandler == null || mappedHandler.getHandler() == null) {
          noHandlerFound(processedRequest, response);
          return;
        }

        // Apply preHandle methods of registered interceptors.
        if (mappedHandler.getInterceptors() != null) {
          for (int i = 0; i < mappedHandler.getInterceptors().length; i++) {
            HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i];
            if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
              triggerAfterCompletion(
                  mappedHandler, interceptorIndex, processedRequest, response, null);
              return;
            }
            interceptorIndex = i;
          }
        }

        // Actually invoke the handler.
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

        // Apply postHandle methods of registered interceptors.
        if (mappedHandler.getInterceptors() != null) {
          for (int i = mappedHandler.getInterceptors().length - 1; i >= 0; i--) {
            HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i];
            interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
          }
        }
      } catch (ModelAndViewDefiningException ex) {
        GrailsUtil.deepSanitize(ex);
        handlerException = ex;
        if (logger.isDebugEnabled()) logger.debug("ModelAndViewDefiningException encountered", ex);
        mv = ex.getModelAndView();
      } catch (Exception ex) {
        GrailsUtil.deepSanitize(ex);
        handlerException = ex;
        Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
        mv = processHandlerException(request, response, handler, ex);
      }

      // Did the handler return a view to render?
      if (mv != null && !mv.wasCleared()) {
        // If an exception occurs in here, like a bad closing tag,
        // we have nothing to render.

        try {
          render(mv, processedRequest, response);
        } catch (Exception e) {
          mv = super.processHandlerException(processedRequest, response, mappedHandler, e);
          handlerException = e;
          render(mv, processedRequest, response);
        }
      } else {
        if (logger.isDebugEnabled()) {
          logger.debug(
              "Null ModelAndView returned to DispatcherServlet with name '"
                  + getServletName()
                  + "': assuming HandlerAdapter completed request handling");
        }
      }

      // Trigger after-completion for successful outcome.
      triggerAfterCompletion(
          mappedHandler, interceptorIndex, processedRequest, response, handlerException);
    } catch (Exception ex) {
      // Trigger after-completion for thrown exception.
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
      throw ex;
    } catch (Error err) {
      ServletException ex = new NestedServletException("Handler processing failed", err);
      // Trigger after-completion for thrown exception.
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
      throw ex;
    } finally {
      // Clean up any resources used by a multipart request.
      if (processedRequest instanceof MultipartHttpServletRequest && processedRequest != request) {
        if (multipartResolver != null)
          this.multipartResolver.cleanupMultipart((MultipartHttpServletRequest) processedRequest);
      }
      request.removeAttribute(MultipartHttpServletRequest.class.getName());

      // Reset thread-bound holders
      if (requestAttributes != null) {
        requestAttributes.requestCompleted();
        WebUtils.storeGrailsWebRequest(previousRequestAttributes);
      }

      LocaleContextHolder.setLocaleContext(previousLocaleContext);

      if (logger.isDebugEnabled()) {
        logger.debug("Cleared thread-bound request context: " + request);
      }
    }
  }
  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);
  }
  /**
   * Creates a Template for the currently executing Request
   *
   * @return The Template for the currently executing request
   * @throws java.io.IOException Thrown when an exception occurs Reading the Template
   * @throws ClassNotFoundException Thrown when the class of the template was not found
   */
  public Template createTemplate() throws IOException, ClassNotFoundException {
    GrailsWebRequest webRequest = getWebRequest();
    String uri = getCurrentRequestUri(webRequest.getCurrentRequest());

    return createTemplate(uri);
  }
Example #24
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;
  }
  /* (non-Javadoc)
   * @see org.springframework.web.servlet.DispatcherServlet#doDispatch(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
   */
  @Override
  protected void doDispatch(final HttpServletRequest request, HttpServletResponse response)
      throws Exception {

    request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, localeResolver);

    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    int interceptorIndex = -1;

    // Expose current LocaleResolver and request as LocaleContext.
    LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();
    LocaleContextHolder.setLocaleContext(
        new LocaleContext() {
          public Locale getLocale() {
            return localeResolver.resolveLocale(request);
          }
        });

    // If the request is an include we need to try to use the original wrapped sitemesh
    // response, otherwise layouts won't work properly
    if (WebUtils.isIncludeRequest(request)) {
      response = useWrappedOrOriginalResponse(response);
    }

    GrailsWebRequest requestAttributes = null;
    RequestAttributes previousRequestAttributes = null;
    Exception handlerException = null;
    boolean isAsyncRequest =
        processedRequest.getAttribute("javax.servlet.async.request_uri") != null;
    try {
      ModelAndView mv;
      boolean errorView = false;
      try {
        Object exceptionAttribute = request.getAttribute(EXCEPTION_ATTRIBUTE);
        // only process multipart requests if an exception hasn't occured
        if (exceptionAttribute == null) {
          processedRequest = checkMultipart(request);
        }
        // Expose current RequestAttributes to current thread.
        previousRequestAttributes = RequestContextHolder.currentRequestAttributes();
        requestAttributes = new GrailsWebRequest(processedRequest, response, getServletContext());
        copyParamsFromPreviousRequest(previousRequestAttributes, requestAttributes);

        // Update the current web request.
        WebUtils.storeGrailsWebRequest(requestAttributes);

        if (logger.isDebugEnabled()) {
          logger.debug("Bound request context to thread: " + request);
          logger.debug("Using response object: " + response.getClass());
        }

        // Determine handler for the current request.
        mappedHandler = getHandler(processedRequest);
        if (mappedHandler == null || mappedHandler.getHandler() == null) {
          noHandlerFound(processedRequest, response);
          return;
        }

        // Apply preHandle methods of registered interceptors.
        if (mappedHandler.getInterceptors() != null) {
          for (int i = 0; i < mappedHandler.getInterceptors().length; i++) {
            HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i];
            if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
              triggerAfterCompletion(
                  mappedHandler, interceptorIndex, processedRequest, response, null);
              return;
            }
            interceptorIndex = i;
          }
        }

        // if this is an async request that has been resumed, then don't execute the action again
        // instead try get the model and view and continue

        if (isAsyncRequest) {
          Object modelAndViewO =
              processedRequest.getAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW);
          if (modelAndViewO != null) {
            mv = (ModelAndView) modelAndViewO;
          } else {
            mv = null;
          }

        } else {
          // Actually invoke the handler.
          HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
          mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
          // if an async request was started simply return
          if (processedRequest.getAttribute(GrailsApplicationAttributes.ASYNC_STARTED) != null) {
            processedRequest.setAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW, mv);
            return;
          }

          // Do we need view name translation?
          if ((ha instanceof AnnotationMethodHandlerAdapter
                  || ha instanceof RequestMappingHandlerAdapter)
              && mv != null
              && !mv.hasView()) {
            mv.setViewName(getDefaultViewName(request));
          }
        }

        // Apply postHandle methods of registered interceptors.
        if (mappedHandler.getInterceptors() != null) {
          for (int i = mappedHandler.getInterceptors().length - 1; i >= 0; i--) {
            HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i];
            interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
          }
        }
      } catch (ModelAndViewDefiningException ex) {
        handlerException = ex;
        if (logger.isDebugEnabled()) {
          logger.debug("ModelAndViewDefiningException encountered", ex);
        }
        mv = ex.getModelAndView();
      } catch (Exception ex) {
        handlerException = ex;
        Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
        mv = processHandlerException(request, response, handler, ex);
        errorView = (mv != null);
      }

      // Did the handler return a view to render?
      if (mv != null && !mv.wasCleared()) {
        // If an exception occurs in here, like a bad closing tag,
        // we have nothing to render.

        try {
          render(mv, processedRequest, response);
          if (isAsyncRequest && (response instanceof GrailsContentBufferingResponse)) {
            GroovyPageLayoutFinder groovyPageLayoutFinder =
                getWebApplicationContext()
                    .getBean("groovyPageLayoutFinder", GroovyPageLayoutFinder.class);
            GrailsContentBufferingResponse bufferingResponse =
                (GrailsContentBufferingResponse) response;
            HttpServletResponse targetResponse = bufferingResponse.getTargetResponse();
            Content content = bufferingResponse.getContent();
            if (content != null) {
              Decorator decorator = groovyPageLayoutFinder.findLayout(request, content);
              SiteMeshWebAppContext webAppContext =
                  new SiteMeshWebAppContext(request, targetResponse, getServletContext());
              if (decorator != null) {
                if (decorator instanceof com.opensymphony.sitemesh.Decorator) {
                  ((com.opensymphony.sitemesh.Decorator) decorator).render(content, webAppContext);
                } else {
                  new OldDecorator2NewDecorator(decorator).render(content, webAppContext);
                }
              } else {
                content.writeOriginal(targetResponse.getWriter());
              }
            }
          }
          if (errorView) {
            WebUtils.clearErrorRequestAttributes(request);
          }
        } catch (Exception e) {
          // Only render the error view if we're not already trying to render it.
          // This prevents a recursion if the error page itself has errors.
          if (request.getAttribute(GrailsApplicationAttributes.RENDERING_ERROR_ATTRIBUTE) == null) {
            request.setAttribute(
                GrailsApplicationAttributes.RENDERING_ERROR_ATTRIBUTE, Boolean.TRUE);

            mv = super.processHandlerException(processedRequest, response, mappedHandler, e);
            handlerException = e;
            if (mv != null) render(mv, processedRequest, response);
          } else {
            request.removeAttribute(GrailsApplicationAttributes.RENDERING_ERROR_ATTRIBUTE);
            logger.warn("Recursive rendering of error view detected.", e);

            try {
              response.setContentType("text/plain");
              response.getWriter().write("Internal server error");
              response.flushBuffer();
            } catch (Exception e2) {
              logger.error("Internal server error - problem rendering error view", e2);
            }

            requestAttributes.setRenderView(false);
            return;
          }
        }
      } else {
        if (logger.isDebugEnabled()) {
          logger.debug(
              "Null ModelAndView returned to DispatcherServlet with name '"
                  + getServletName()
                  + "': assuming HandlerAdapter completed request handling");
        }
      }

      // Trigger after-completion for successful outcome.
      triggerAfterCompletion(
          mappedHandler, interceptorIndex, processedRequest, response, handlerException);
    } catch (Exception ex) {
      // Trigger after-completion for thrown exception.
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
      throw ex;
    } catch (Error err) {
      ServletException ex = new NestedServletException("Handler processing failed", err);
      // Trigger after-completion for thrown exception.
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
      throw ex;
    } finally {
      // Clean up any resources used by a multipart request.
      if (processedRequest instanceof MultipartHttpServletRequest) {
        if (multipartResolver != null) {
          multipartResolver.cleanupMultipart((MultipartHttpServletRequest) processedRequest);
        }
      }
      request.removeAttribute(MultipartHttpServletRequest.class.getName());

      // Reset thread-bound holders
      if (requestAttributes != null) {
        requestAttributes.requestCompleted();
        if (previousRequestAttributes instanceof GrailsWebRequest) {
          WebUtils.storeGrailsWebRequest((GrailsWebRequest) previousRequestAttributes);
        } else {
          RequestContextHolder.setRequestAttributes(previousRequestAttributes);
        }
      }

      LocaleContextHolder.setLocaleContext(previousLocaleContext);

      if (logger.isDebugEnabled()) {
        logger.debug("Cleared thread-bound request context: " + request);
      }
    }
  }