@Override
  public ActionForward execute(
      ActionMapping actionMapping,
      ActionForm actionForm,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

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

    themeDisplay.setAjax(true);

    String ajaxId = request.getParameter("ajax_id");

    long companyId = PortalUtil.getCompanyId(request);
    User user = PortalUtil.getUser(request);
    Layout layout = (Layout) request.getAttribute(WebKeys.LAYOUT);
    String portletId = ParamUtil.getString(request, "p_p_id");

    Portlet portlet = PortletLocalServiceUtil.getPortletById(companyId, portletId);

    String columnId = ParamUtil.getString(request, "p_p_col_id");
    int columnPos = ParamUtil.getInteger(request, "p_p_col_pos");
    int columnCount = ParamUtil.getInteger(request, "p_p_col_count");
    boolean boundary = ParamUtil.getBoolean(request, "p_p_boundary", true);
    boolean decorate = ParamUtil.getBoolean(request, "p_p_decorate", true);
    boolean staticPortlet = ParamUtil.getBoolean(request, "p_p_static");
    boolean staticStartPortlet = ParamUtil.getBoolean(request, "p_p_static_start");

    if (staticPortlet) {
      portlet = (Portlet) portlet.clone();

      portlet.setStatic(true);
      portlet.setStaticStart(staticStartPortlet);
    }

    if (ajaxId != null) {
      response.setHeader("Ajax-ID", ajaxId);
    }

    WindowState windowState =
        WindowStateFactory.getWindowState(ParamUtil.getString(request, "p_p_state"));

    PortalUtil.updateWindowState(portletId, user, layout, windowState, request);

    request =
        PortletContainerUtil.setupOptionalRenderParameters(
            request, null, columnId, columnPos, columnCount, boundary, decorate);

    PortletContainerUtil.render(request, response, portlet);

    return null;
  }
  protected HttpServletRequest getOwnerLayoutRequestWrapper(
      HttpServletRequest request, Portlet portlet) throws Exception {

    if (!PropsValues.PORTLET_EVENT_DISTRIBUTION_LAYOUT_SET) {
      return request;
    }

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

    Layout currentLayout = themeDisplay.getLayout();

    Layout requestLayout = (Layout) request.getAttribute(WebKeys.LAYOUT);

    List<LayoutTypePortlet> layoutTypePortlets =
        PortletContainerUtil.getLayoutTypePortlets(requestLayout);

    Layout ownerLayout = null;
    LayoutTypePortlet ownerLayoutTypePortlet = null;

    for (LayoutTypePortlet layoutTypePortlet : layoutTypePortlets) {
      if (layoutTypePortlet.hasPortletId(portlet.getPortletId())) {
        ownerLayoutTypePortlet = layoutTypePortlet;

        ownerLayout = layoutTypePortlet.getLayout();

        break;
      }
    }

    if ((ownerLayout != null) && !currentLayout.equals(ownerLayout)) {
      ThemeDisplay themeDisplayClone = (ThemeDisplay) themeDisplay.clone();

      themeDisplayClone.setLayout(ownerLayout);
      themeDisplayClone.setLayoutTypePortlet(ownerLayoutTypePortlet);

      TempAttributesServletRequest tempAttributesServletRequest =
          new TempAttributesServletRequest(request);

      tempAttributesServletRequest.setTempAttribute(WebKeys.THEME_DISPLAY, themeDisplayClone);
      tempAttributesServletRequest.setTempAttribute(WebKeys.LAYOUT, ownerLayout);

      return tempAttributesServletRequest;
    }

    return request;
  }
  public static void doTag(
      String portletName,
      String instanceId,
      String queryString,
      String settingsScope,
      String defaultPreferences,
      boolean persistSettings,
      PageContext pageContext,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    if (pageContext != null) {
      response = new PipingServletResponse(response, pageContext.getOut());
    }

    PortletInstance portletInstance = PortletInstance.fromPortletInstanceKey(portletName);

    if (Validator.isNotNull(instanceId)) {
      portletInstance =
          new PortletInstance(
              portletInstance.getPortletName(), portletInstance.getUserId(), instanceId);
    }

    RestrictPortletServletRequest restrictPortletServletRequest =
        new RestrictPortletServletRequest(PortalUtil.getOriginalServletRequest(request));

    queryString =
        PortletParameterUtil.addNamespace(portletInstance.getPortletInstanceKey(), queryString);

    Map<String, String[]> parameterMap = request.getParameterMap();

    if (!Objects.equals(portletInstance.getPortletInstanceKey(), request.getParameter("p_p_id"))) {

      parameterMap = MapUtil.filterByKeys(parameterMap, (key) -> !key.startsWith("p_p_"));
    }

    request =
        DynamicServletRequest.addQueryString(
            restrictPortletServletRequest, parameterMap, queryString, false);

    try {
      request.setAttribute(WebKeys.RENDER_PORTLET_RESOURCE, Boolean.TRUE);

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

      Portlet portlet =
          getPortlet(themeDisplay.getCompanyId(), portletInstance.getPortletInstanceKey());

      Stack<String> embeddedPortletIds = _embeddedPortletIds.get();

      if (embeddedPortletIds == null) {
        embeddedPortletIds = new Stack<>();

        _embeddedPortletIds.set(embeddedPortletIds);
      }

      if (embeddedPortletIds.search(portlet.getPortletId()) > -1) {
        String errorMessage = LanguageUtil.get(request, "the-application-cannot-include-itself");

        request.setAttribute("liferay-portlet:runtime:errorMessage", errorMessage);

        PortalIncludeUtil.include(pageContext, _ERROR_PAGE);

        return;
      }

      if (themeDisplay.isStateMaximized()) {
        LayoutTypePortlet layoutTypePortlet = themeDisplay.getLayoutTypePortlet();

        if (layoutTypePortlet.hasStateMaxPortletId(portletInstance.getPortletInstanceKey())) {

          // A portlet in the maximized state has already been
          // processed

          return;
        }
      }

      Layout layout = themeDisplay.getLayout();

      request.setAttribute(WebKeys.SETTINGS_SCOPE, settingsScope);

      JSONObject jsonObject = null;

      boolean writeJSONObject = false;

      LayoutTypePortlet layoutTypePortlet = themeDisplay.getLayoutTypePortlet();

      if (persistSettings && !layoutTypePortlet.isPortletEmbedded(portlet.getPortletId())) {

        PortletPreferencesFactoryUtil.getLayoutPortletSetup(
            themeDisplay.getCompanyId(),
            themeDisplay.getScopeGroupId(),
            PortletKeys.PREFS_OWNER_TYPE_LAYOUT,
            PortletKeys.PREFS_PLID_SHARED,
            portletInstance.getPortletInstanceKey(),
            defaultPreferences);

        writeJSONObject = true;
      }

      if (PortletPreferencesLocalServiceUtil.getPortletPreferencesCount(
              PortletKeys.PREFS_OWNER_TYPE_LAYOUT,
              themeDisplay.getPlid(),
              portletInstance.getPortletInstanceKey())
          < 1) {

        PortletPreferencesFactoryUtil.getLayoutPortletSetup(
            layout, portletInstance.getPortletInstanceKey(), defaultPreferences);
        PortletPreferencesFactoryUtil.getPortletSetup(
            request, portletInstance.getPortletInstanceKey(), defaultPreferences);

        PortletLayoutListener portletLayoutListener = portlet.getPortletLayoutListenerInstance();

        if (portletLayoutListener != null) {
          portletLayoutListener.onAddToLayout(
              portletInstance.getPortletInstanceKey(), themeDisplay.getPlid());
        }

        writeJSONObject = true;
      }

      if (writeJSONObject) {
        jsonObject = JSONFactoryUtil.createJSONObject();

        PortletJSONUtil.populatePortletJSONObject(request, StringPool.BLANK, portlet, jsonObject);
      }

      if (jsonObject != null) {
        PortletJSONUtil.writeHeaderPaths(response, jsonObject);
      }

      embeddedPortletIds.push(portletInstance.getPortletInstanceKey());

      PortletContainerUtil.render(request, response, portlet);

      embeddedPortletIds.pop();

      if (jsonObject != null) {
        PortletJSONUtil.writeFooterPaths(response, jsonObject);
      }
    } finally {
      restrictPortletServletRequest.mergeSharedAttributes();
    }
  }