/**
   * The processrender() method handles the creation of the returned HTML either for a full page
   * render or in the case of an AJAX call The first request, Ajax is not enabled (means no
   * ajaxRequest parameter in the request) and hence the super.processRender() method is called.
   * This will hence call the processrender() of the Lifecycle object as this method is not
   * overidden in UIPortalApplicationLifecycle. There we simply render the bounded template (groovy
   * usually). Note that bounded template are also defined in component annotations, so for the
   * current class it is UIPortalApplication.gtmpl On second calls, request have the "ajaxRequest"
   * parameter set to true in the URL. In that case the algorithm is a bit more complex: a) The list
   * of components that should be updated is extracted using the
   * context.getUIComponentToUpdateByAjax() method. That list was setup during the process action
   * phase b) Portlets and other UI components to update are split in 2 different lists c) Portlets
   * full content are returned and set with the tag <div class="PortalResponse"> d) Block to updates
   * (which are UI components) are set within the <div class="PortalResponseData"> tag e) Then the
   * scripts and the skins to reload are set in the <div class="PortalResponseScript">
   */
  public void processRender(WebuiRequestContext context) throws Exception {
    Writer w = context.getWriter();
    if (!context.useAjax()) {
      super.processRender(context);
    } else {
      PortalRequestContext pcontext = (PortalRequestContext) context;

      UIMaskWorkspace uiMaskWS = getChildById(UIPortalApplication.UI_MASK_WS_ID);
      if (uiMaskWS.isUpdated()) pcontext.addUIComponentToUpdateByAjax(uiMaskWS);
      if (getUIPopupMessages().hasMessage()) {
        pcontext.addUIComponentToUpdateByAjax(getUIPopupMessages());
      }

      Set<UIComponent> list = context.getUIComponentToUpdateByAjax();
      List<UIPortlet> uiPortlets = new ArrayList<UIPortlet>(3);
      List<UIComponent> uiDataComponents = new ArrayList<UIComponent>(5);

      if (list != null) {
        for (UIComponent uicomponent : list) {
          if (uicomponent instanceof UIPortlet) uiPortlets.add((UIPortlet) uicomponent);
          else uiDataComponents.add(uicomponent);
        }
      }
      w.write("<div class=\"PortalResponse\">");
      w.write("<div class=\"PortalResponseData\">");
      for (UIComponent uicomponent : uiDataComponents) {
        if (log.isDebugEnabled())
          log.debug("AJAX call: Need to refresh the UI component " + uicomponent.getName());
        renderBlockToUpdate(uicomponent, context, w);
      }
      w.write("</div>");

      if (!context.getFullRender()) {
        for (UIPortlet uiPortlet : uiPortlets) {
          if (log.isDebugEnabled())
            log.debug("AJAX call: Need to refresh the Portlet " + uiPortlet.getWindowId());

          w.write("<div class=\"PortletResponse\" style=\"display: none\">");
          w.append(
              "<div class=\"PortletResponsePortletId\">"
                  + uiPortlet.getExoWindowID().getUniqueID()
                  + "</div>");
          w.append("<div class=\"PortletResponseData\">");

          /*
           * If the portlet is using our UI framework or supports it then it
           * will return a set of block to updates. If there is not block to
           * update the javascript client will see that as a full refresh of the
           * content part
           */
          uiPortlet.processRender(context);

          w.append("</div>");
          w.append("<div class=\"PortletResponseScript\"></div>");
          w.write("</div>");
        }
      }

      w.write("<div class=\"PortalResponseScript\">");
      w.write(pcontext.getJavascriptManager().getJavascript());
      w.write("eXo.core.Browser.onLoad();\n");
      w.write(pcontext.getJavascriptManager().getCustomizedOnLoadScript());
      String skin = getAddSkinScript(list);
      if (skin != null) {
        w.write(skin);
      }
      w.write("</div>");
      w.write("</div>");
    }
  }