@Override
  public void execute() throws BridgeException {

    logger.debug(Logger.SEPARATOR);
    logger.debug(
        "execute(RenderRequest, RenderResponse) portletName=[{0}] portletMode=[{1}]",
        portletName, renderRequest.getPortletMode());

    Object renderPartAttribute = renderRequest.getAttribute(RenderRequest.RENDER_PART);

    if ((renderPartAttribute != null) && renderPartAttribute.equals(RenderRequest.RENDER_HEADERS)) {
      doFacesHeaders(renderRequest, renderResponse);
    } else {

      try {
        execute(null);
      } catch (BridgeException e) {
        throw e;
      } catch (Throwable t) {
        throw new BridgeException(t);
      } finally {
        cleanup(renderRequest);
      }

      logger.debug(Logger.SEPARATOR);
    }
  }
  /**
   * Sets the "javax.portlet.faces.viewIdHistory.<code>portletMode</code>" session attribute
   * according to the requirements in Section 5.4.3 of the Bridge Spec. There is no corresponding
   * getter method, because the value is meant to be retrieved by developers via an EL expression.
   *
   * @param viewId The current Faces viewId.
   */
  protected void setViewHistory(String viewId) {

    String attributeName =
        Bridge.VIEWID_HISTORY.concat(".").concat(renderRequest.getPortletMode().toString());
    PortletSession portletSession = renderRequest.getPortletSession();
    portletSession.setAttribute(attributeName, viewId);
  }
  /**
   * Sets the "javax.portlet.faces.viewIdHistory.<code>portletMode</code>" session attribute
   * according to the requirements in Section 5.4.3 of the Bridge Spec. There is no corresponding
   * getter method, because the value is meant to be retrieved by developers via an EL expression.
   *
   * @param viewId The current Faces viewId.
   */
  protected void setViewHistory(String viewId) {
    StringBuilder buf = new StringBuilder();
    buf.append(Bridge.VIEWID_HISTORY);
    buf.append(StringPool.PERIOD);
    buf.append(renderRequest.getPortletMode());

    String attributeName = buf.toString();
    PortletSession portletSession = renderRequest.getPortletSession();
    portletSession.setAttribute(attributeName, viewId);
  }
Esempio n. 4
0
 /**
  * Override doDispatch method for handling custom portlet modes.
  *
  * @see javax.portlet.GenericPortlet#doDispatch(javax.portlet.RenderRequest,
  *     javax.portlet.RenderResponse)
  */
 protected void doDispatch(RenderRequest request, RenderResponse response)
     throws PortletException, IOException {
   if (!WindowState.MINIMIZED.equals(request.getWindowState())) {
     PortletMode mode = request.getPortletMode();
     if (CUSTOM_CONFIG_MODE.equals(mode)) {
       doCustomConfigure(request, response);
       return;
     }
   }
   super.doDispatch(request, response);
 }
  @Override
  protected void writeAjaxPage(
      RenderRequest request, RenderResponse response, Window window, Application application)
      throws IOException, MalformedURLException, PortletException {
    MailApplication mailApplication = (MailApplication) application;

    // user is set in the portlet listener by the application
    if (mailApplication.getController().getUser() == null) {
      // normally, the portal takes care of this
      // this branch is in case the user has not been registered in the controller
      writeNotLoggedInPageHtml(request, response, window);
    } else if (PortletMode.VIEW.equals(request.getPortletMode())
        && WindowState.NORMAL.equals(request.getWindowState())) {
      mailApplication.writeViewPageHtml(request, response, window);
    } else {
      // this includes other modes as well as the maximized state
      super.writeAjaxPage(request, response, window, application);
    }
  }
  protected void execute(String renderRedirectViewId) throws BridgeException, IOException {

    init(renderRequest, renderResponse, Bridge.PortletPhase.RENDER_PHASE);

    // If the portlet mode has not changed, then restore the faces view root and messages that would
    // have been saved during the ACTION_PHASE of the portlet lifecycle. Section 5.4.1 requires that
    // the
    // BridgeRequestScope must not be restored if there is a change in portlet modes detected.
    boolean facesLifecycleExecuted = bridgeRequestScope.isFacesLifecycleExecuted();
    bridgeRequestScope.restoreState(facesContext);

    if (bridgeRequestScope.isPortletModeChanged()) {
      bridgeRequestScopeCache.remove(bridgeRequestScope.getId());
    }

    // If a render-redirect URL was specified, then it is necessary to create a new view from the
    // URL and place it
    // in the FacesContext.
    if (renderRedirectViewId != null) {
      renderRequest.setAttribute(BridgeExt.RENDER_REDIRECT_AFTER_DISPATCH, Boolean.TRUE);

      ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
      UIViewRoot uiViewRoot = viewHandler.createView(facesContext, renderRedirectViewId);
      facesContext.setViewRoot(uiViewRoot);
      logger.debug("Performed render-redirect to viewId=[{0}]", renderRedirectViewId);
    }

    // NOTE: PROPOSE-FOR-BRIDGE3-API Actually, the proposal would be to REMOVE
    // Bridge.IS_POSTBACK_ATTRIBUTE from the Bridge API, because JSF 2.0 introduced the
    // FacesContext#isPostBack() method.
    // http://javaserverfaces.java.net/nonav/docs/2.0/javadocs/javax/faces/context/FacesContext.html#isPostback()
    if (bridgeRequestScope.getBeganInPhase() == Bridge.PortletPhase.ACTION_PHASE) {

      ExternalContext externalContext = facesContext.getExternalContext();
      externalContext.getRequestMap().put(Bridge.IS_POSTBACK_ATTRIBUTE, Boolean.TRUE);
    }

    logger.debug(
        "portletName=[{0}] facesLifecycleExecuted=[{1}]", portletName, facesLifecycleExecuted);

    // If the JSF lifecycle executed back in the ACTION_PHASE of the portlet lifecycle, then
    if (facesLifecycleExecuted) {

      // TCK TestPage054: prpUpdatedFromActionTest
      PhaseEvent restoreViewPhaseEvent =
          new PhaseEvent(facesContext, PhaseId.RESTORE_VIEW, facesLifecycle);
      PhaseListener[] phaseListeners = facesLifecycle.getPhaseListeners();

      for (PhaseListener phaseListener : phaseListeners) {

        if (phaseListener instanceof IPCPhaseListener) {
          phaseListener.afterPhase(restoreViewPhaseEvent);

          break;
        }
      }
    }

    // Otherwise, in accordance with Section 5.2.6 of the Spec, execute the JSF lifecycle so that
    // ONLY the
    // RESTORE_VIEW phase executes. Note that this is accomplished by the
    // RenderRequestPhaseListener.
    else {

      try {
        ExternalContext externalContext = facesContext.getExternalContext();
        String viewId = getFacesViewId(externalContext);
        logger.debug("Executing Faces lifecycle for viewId=[{0}]", viewId);
      } catch (BridgeException e) {
        logger.error("Unable to get viewId due to {0}", e.getClass().getSimpleName());
        throw e;
      }

      // Attach the JSF 2.2 client window to the JSF lifecycle so that Faces Flows can be utilized.
      attachClientWindowToLifecycle(facesContext, facesLifecycle);

      // Execute the JSF lifecycle.
      facesLifecycle.execute(facesContext);
    }

    // If there were any "handled" exceptions queued, then throw a BridgeException.
    Throwable handledException = getJSF2HandledException(facesContext);

    if (handledException != null) {
      throw new BridgeException(handledException);
    }

    // Otherwise, if there were any "unhandled" exceptions queued, then throw a BridgeException.
    Throwable unhandledException = getJSF2UnhandledException(facesContext);

    if (unhandledException != null) {
      throw new BridgeException(unhandledException);
    }

    // Otherwise, if the PortletMode has changed, and a navigation-rule hasn't yet fired (which
    // could have happened
    // in the EVENT_PHASE), then switch to the appropriate PortletMode and navigate to the current
    // viewId in the
    // UIViewRoot.
    if (bridgeRequestScope.isPortletModeChanged() && !bridgeRequestScope.isNavigationOccurred()) {
      BridgeNavigationHandler bridgeNavigationHandler = getBridgeNavigationHandler(facesContext);
      PortletMode fromPortletMode = bridgeRequestScope.getPortletMode();
      PortletMode toPortletMode = renderRequest.getPortletMode();
      bridgeNavigationHandler.handleNavigation(facesContext, fromPortletMode, toPortletMode);
    }

    // Determines whether or not lifecycle incongruities should be managed.
    boolean manageIncongruities =
        PortletConfigParam.ManageIncongruities.getBooleanValue(portletConfig);

    // Now that we're executing the RENDER_PHASE of the Portlet lifecycle, before the JSF
    // RENDER_RESPONSE phase is executed, we have to fix some incongruities between the Portlet
    // lifecycle and the JSF lifecycle that may have occurred during the ACTION_PHASE of the Portlet
    // lifecycle.
    if (manageIncongruities) {
      incongruityContext.makeCongruous(facesContext);
    }

    // Execute the RENDER_RESPONSE phase of the faces lifecycle.
    logger.debug("Executing Faces render");
    facesLifecycle.render(facesContext);

    // Set the view history according to Section 5.4.3 of the Bridge Spec.
    setViewHistory(facesContext.getViewRoot().getViewId());

    // Spec 6.6 (Namespacing)
    indicateNamespacingToConsumers(facesContext.getViewRoot(), renderResponse);

    // If a render-redirect occurred, then
    ExternalContext externalContext = facesContext.getExternalContext();
    Writer writer = getResponseOutputWriter(externalContext);

    Map<String, Object> requestMap = externalContext.getRequestMap();
    Boolean renderRedirect = (Boolean) requestMap.remove(BridgeExt.RENDER_REDIRECT);

    if ((renderRedirect != null) && renderRedirect) {

      // Cleanup the old FacesContext since a new one will be created in the recursive method call
      // below.
      facesContext.responseComplete();
      facesContext.release();

      // If the render-redirect standard feature is enabled in web.xml or portlet.xml, then the
      // ResponseOutputWriter has buffered up markup that must be discarded. This is because we
      // don't want the
      // markup from the original Faces view to be included with the markup of Faces view found in
      // the
      // redirect URL.
      if (writer instanceof RenderRedirectWriter) {
        RenderRedirectWriter responseOutputWriter = (RenderRedirectWriter) writer;
        responseOutputWriter.discard();
      }

      // Recursively call this method with the render-redirect URL so that the RENDER_RESPONSE phase
      // of the
      // JSF lifecycle will be re-executed according to the new Faces viewId found in the redirect
      // URL.
      renderRedirectViewId = (String) requestMap.remove(BridgeExt.RENDER_REDIRECT_VIEW_ID);

      execute(renderRedirectViewId);
    }

    // Otherwise,
    else {

      // In the case that a render-redirect took place, need to render the buffered markup to the
      // response.
      if (writer instanceof RenderRedirectWriter) {
        RenderRedirectWriter responseOutputWriter = (RenderRedirectWriter) writer;
        responseOutputWriter.render();
      }
    }
  }