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);
}
}
}
}
}
Aggregations