@Override
  protected void processFilter(
      HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
      throws Exception {

    request.setAttribute(SKIP_FILTER, Boolean.TRUE);

    String key = getCacheKey(request);

    long companyId = PortalInstances.getCompanyId(request);

    CacheResponseData cacheResponseData = CacheUtil.getCacheResponseData(companyId, key);

    if (cacheResponseData == null) {
      if (!isCacheableData(companyId, request)) {
        if (_log.isDebugEnabled()) {
          _log.debug("Request is not cacheable " + key);
        }

        processFilter(CacheFilter.class, request, response, filterChain);

        return;
      }

      if (_log.isInfoEnabled()) {
        _log.info("Caching request " + key);
      }

      BufferCacheServletResponse bufferCacheServletResponse =
          new BufferCacheServletResponse(response);

      processFilter(CacheFilter.class, request, bufferCacheServletResponse, filterChain);

      cacheResponseData = new CacheResponseData(bufferCacheServletResponse);

      LastPath lastPath = (LastPath) request.getAttribute(WebKeys.LAST_PATH);

      if (lastPath != null) {
        cacheResponseData.setAttribute(WebKeys.LAST_PATH, lastPath);
      }

      // Cache the result if and only if there is a result and the request
      // is cacheable. We have to test the cacheability of a request twice
      // because the user could have been authenticated after the initial
      // test.

      String cacheControl =
          GetterUtil.getString(bufferCacheServletResponse.getHeader(HttpHeaders.CACHE_CONTROL));

      if ((bufferCacheServletResponse.getStatus() == HttpServletResponse.SC_OK)
          && !cacheControl.contains(HttpHeaders.PRAGMA_NO_CACHE_VALUE)
          && isCacheableRequest(request)
          && isCacheableResponse(bufferCacheServletResponse)) {

        CacheUtil.putCacheResponseData(companyId, key, cacheResponseData);
      }
    } else {
      LastPath lastPath = (LastPath) cacheResponseData.getAttribute(WebKeys.LAST_PATH);

      if (lastPath != null) {
        HttpSession session = request.getSession();

        session.setAttribute(WebKeys.LAST_PATH, lastPath);
      }
    }

    CacheResponseUtil.write(response, cacheResponseData);
  }
  public ActionForward execute(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    HeaderCacheServletResponse headerCacheServletResponse = null;

    if (response instanceof HeaderCacheServletResponse) {
      headerCacheServletResponse = (HeaderCacheServletResponse) response;
    } else {
      headerCacheServletResponse = new HeaderCacheServletResponse(response);
    }

    ThemeDisplay themeDisplay = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);

    Layout layout = themeDisplay.getLayout();

    Boolean layoutDefault = (Boolean) request.getAttribute(WebKeys.LAYOUT_DEFAULT);

    if ((layoutDefault != null) && (layoutDefault.booleanValue())) {
      Layout requestedLayout = (Layout) request.getAttribute(WebKeys.REQUESTED_LAYOUT);

      if (requestedLayout != null) {
        String redirectParam = "redirect";

        if (Validator.isNotNull(PropsValues.AUTH_LOGIN_PORTLET_NAME)) {
          redirectParam =
              PortalUtil.getPortletNamespace(PropsValues.AUTH_LOGIN_PORTLET_NAME) + redirectParam;
        }

        String authLoginURL = null;

        if (PrefsPropsUtil.getBoolean(
            themeDisplay.getCompanyId(),
            PropsKeys.CAS_AUTH_ENABLED,
            PropsValues.CAS_AUTH_ENABLED)) {

          authLoginURL = themeDisplay.getURLSignIn();
        }

        if (Validator.isNull(authLoginURL)) {
          authLoginURL = PortalUtil.getCommunityLoginURL(themeDisplay);
        }

        if (Validator.isNull(authLoginURL)) {
          authLoginURL = PropsValues.AUTH_LOGIN_URL;
        }

        if (Validator.isNull(authLoginURL)) {
          PortletURL loginURL = LoginUtil.getLoginURL(request, themeDisplay.getPlid());

          authLoginURL = loginURL.toString();
        }

        String currentURL = PortalUtil.getCurrentURL(request);

        authLoginURL = HttpUtil.setParameter(authLoginURL, redirectParam, currentURL);

        if (_log.isDebugEnabled()) {
          _log.debug("Redirect requested layout to " + authLoginURL);
        }

        headerCacheServletResponse.sendRedirect(authLoginURL);
      } else {
        String redirect = PortalUtil.getLayoutURL(layout, themeDisplay);

        if (_log.isDebugEnabled()) {
          _log.debug("Redirect default layout to " + redirect);
        }

        headerCacheServletResponse.sendRedirect(redirect);
      }

      return null;
    }

    long plid = ParamUtil.getLong(request, "p_l_id");

    if (_log.isDebugEnabled()) {
      _log.debug("p_l_id is " + plid);
    }

    if (plid > 0) {
      ActionForward actionForward =
          processLayout(mapping, request, headerCacheServletResponse, plid);

      String contentType = response.getContentType();

      CacheResponseUtil.setHeaders(response, headerCacheServletResponse.getHeaders());

      if (contentType != null) {
        response.setContentType(contentType);
      }

      return actionForward;
    } else {
      try {
        forwardLayout(request);

        return mapping.findForward(ActionConstants.COMMON_FORWARD_JSP);
      } catch (Exception e) {
        PortalUtil.sendError(e, request, headerCacheServletResponse);

        CacheResponseUtil.setHeaders(response, headerCacheServletResponse.getHeaders());

        return null;
      }
    }
  }