Search in sources :

Example 1 with CapturingWriter

use of com.liferay.faces.bridge.context.internal.CapturingWriter in project liferay-faces-bridge-impl by liferay.

the class BridgePhaseHeaderRenderCommon method executeRender.

protected void executeRender(String renderRedirectViewId, Bridge.PortletPhase portletPhase) throws BridgeException, IOException {
    RenderRequest renderRequest = getRenderRequest();
    MimeResponse mimeResponse = getMimeResponse();
    init(renderRequest, mimeResponse, portletPhase);
    // Determine whether or not the Faces lifecycle was already executed.
    boolean facesLifecycleExecuted = bridgeRequestScope.isFacesLifecycleExecuted();
    // Restore the faces view root and messages that would have been saved during the ACTION_PHASE.
    bridgeRequestScope.restoreState(facesContext);
    // scope must not be maintained if a redirect has occurred.
    if (bridgeRequestScope.isPortletModeChanged() || bridgeRequestScope.isRedirectOccurred()) {
        bridgeRequestScopeCache.removeValue(bridgeRequestScope.getId());
    }
    // 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);
    } else // _facesViewIdRender request parameter.
    if (bridgeRequestScope.isRedirectOccurred()) {
        // TCK (redirectEventTest)
        facesLifecycleExecuted = false;
    }
    // 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: 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;
            }
        }
    } else // 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 HeaderRequestPhaseListener.
    {
        ExternalContext externalContext = facesContext.getExternalContext();
        try {
            String viewId = getFacesViewId(externalContext);
            logger.debug("Executing Faces lifecycle for viewId=[{0}]", viewId);
        }// lifecycle has already happened in the HEADER_PHASE.
         catch (BridgeException e) {
            // TCK (portletSetsInvalidViewPathTest)
            // TCK (exceptionThrownWhenNoDefaultViewIdTest)
            Writer responseOutputWriter = getResponseOutputWriter(externalContext);
            if (responseOutputWriter instanceof CapturingWriter) {
                CapturingWriter capturingWriter = (CapturingWriter) responseOutputWriter;
                renderRequest.setAttribute(Bridge.RENDER_RESPONSE_OUTPUT, capturingWriter.getWriterOperations());
            }
            logger.error("Unable to get viewId due to {0}", e.getClass().getSimpleName());
            if (e instanceof BridgeInvalidViewPathException) {
                renderRequest.setAttribute(HANDLING_BRIDGE_INVALID_VIEW_PATH_EXCEPTION, true);
                queueHandleableException(renderRequest, facesContext, e);
            } else {
                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.
        if (isHandlingBridgeInvalidViewPathException(renderRequest)) {
            try {
                facesLifecycle.execute(facesContext);
            } catch (FacesException e) {
                Throwable cause = e.getCause();
                if ((cause != null) && (cause instanceof BridgeInvalidViewPathException)) {
                    throw (BridgeException) cause;
                } else {
                    throw e;
                }
            } finally {
                renderRequest.removeAttribute(HANDLING_BRIDGE_INVALID_VIEW_PATH_EXCEPTION);
            }
        } else {
            facesLifecycle.execute(facesContext);
        }
    }
    throwQueuedExceptionIfNecessary(facesContext);
    // 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);
    // 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(), mimeResponse);
    // If a render-redirect occurred, then
    ExternalContext externalContext = facesContext.getExternalContext();
    Map<String, Object> requestMap = externalContext.getRequestMap();
    Boolean renderRedirect = (Boolean) requestMap.remove(BridgeExt.RENDER_REDIRECT);
    Writer responseOutputWriter = getResponseOutputWriter(externalContext);
    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();
        // redirect URL.
        if (responseOutputWriter instanceof CapturingWriter) {
            CapturingWriter capturingWriter = (CapturingWriter) responseOutputWriter;
            capturingWriter.getWriterOperations().clear();
        }
        // 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);
        executeRender(renderRedirectViewId, portletPhase);
    } else // Otherwise,
    {
        // HEADER_PHASE or that a render-redirect executed in the HEADER_PHASE or RESOURCE_PHASE.
        if (responseOutputWriter instanceof CapturingWriter) {
            CapturingWriter capturingWriter = (CapturingWriter) responseOutputWriter;
            List<WriterOperation> writerOperations = capturingWriter.getWriterOperations();
            if (writerOperations != null) {
                // that the markup will be written to the response.
                if (portletPhase == Bridge.PortletPhase.RENDER_PHASE) {
                    for (WriterOperation writerOperation : writerOperations) {
                        writerOperation.invoke(responseOutputWriter);
                    }
                } else // Otherwise, since running in the HEADER_PHASE, save the list of writer operations so that the
                // markup will be rendered in the subsequent RENDER_PHASE.
                {
                    renderRequest.setAttribute(Bridge.RENDER_RESPONSE_OUTPUT, writerOperations);
                }
            }
        }
    }
}
Also used : PhaseEvent(javax.faces.event.PhaseEvent) ViewHandler(javax.faces.application.ViewHandler) MimeResponse(javax.portlet.MimeResponse) RenderRequest(javax.portlet.RenderRequest) BridgeNavigationHandler(com.liferay.faces.bridge.application.internal.BridgeNavigationHandler) FacesException(javax.faces.FacesException) PortletMode(javax.portlet.PortletMode) BridgeException(javax.portlet.faces.BridgeException) CapturingWriter(com.liferay.faces.bridge.context.internal.CapturingWriter) BridgeInvalidViewPathException(javax.portlet.faces.BridgeInvalidViewPathException) ExternalContext(javax.faces.context.ExternalContext) IPCPhaseListener(com.liferay.faces.bridge.event.internal.IPCPhaseListener) PhaseListener(javax.faces.event.PhaseListener) WriterOperation(com.liferay.faces.bridge.context.internal.WriterOperation) UIViewRoot(javax.faces.component.UIViewRoot) IPCPhaseListener(com.liferay.faces.bridge.event.internal.IPCPhaseListener) CapturingWriter(com.liferay.faces.bridge.context.internal.CapturingWriter) Writer(java.io.Writer)

Aggregations

BridgeNavigationHandler (com.liferay.faces.bridge.application.internal.BridgeNavigationHandler)1 CapturingWriter (com.liferay.faces.bridge.context.internal.CapturingWriter)1 WriterOperation (com.liferay.faces.bridge.context.internal.WriterOperation)1 IPCPhaseListener (com.liferay.faces.bridge.event.internal.IPCPhaseListener)1 Writer (java.io.Writer)1 FacesException (javax.faces.FacesException)1 ViewHandler (javax.faces.application.ViewHandler)1 UIViewRoot (javax.faces.component.UIViewRoot)1 ExternalContext (javax.faces.context.ExternalContext)1 PhaseEvent (javax.faces.event.PhaseEvent)1 PhaseListener (javax.faces.event.PhaseListener)1 MimeResponse (javax.portlet.MimeResponse)1 PortletMode (javax.portlet.PortletMode)1 RenderRequest (javax.portlet.RenderRequest)1 BridgeException (javax.portlet.faces.BridgeException)1 BridgeInvalidViewPathException (javax.portlet.faces.BridgeInvalidViewPathException)1