// Make sure that at a minimum the current render parameters are carried forward
response.setRenderParameters(request.getParameterMap());
FacesContext context = null;
Lifecycle lifecycle = null;
String scopeId = getRequestScopeId(request);
if (scopeId != null)
{
// Its possible we didn't detect the mode change but its the wrong scope
// as the scope is encoded with the mode -- confirm its right
StringBuffer sb = new StringBuffer(10);
String modeCheck = sb.append(":").append(request.getPortletMode().toString()).append(":").toString();
if (scopeId.indexOf(modeCheck) < 0 )
{
// scope is for a different mode
scopeId = null;
}
}
boolean restoredScope = false;
restoredScope = restoreBridgeRequestScopeData(request, scopeId);
try
{
lifecycle = getLifecycle();
// Get the FacesContext instance for this request
context = getFacesContext(request, response, lifecycle, null);
if (restoredScope)
{
// only restores if a render has never occurred in this scope
// once a render occurs, the view is saved/restored via Faces
restoreFacesView(context, scopeId);
}
// in case a prior scope was managed temporarily on the session -- remove it
// also ensure that the scopeId is now carried forward as a renderParameter
request.getPortletSession().removeAttribute(BRIDGE_PACKAGE_PREFIX + REQUEST_SCOPE_ID_RENDER_PARAM);
if (scopeId != null)
{
response.setRenderParameter(REQUEST_SCOPE_ID_RENDER_PARAM, scopeId);
}
// add self as PhaseListener to prevent action phase from executing (after restoreView)
lifecycle.addPhaseListener(this);
// For actions we only execute the lifecycle phase
lifecycle.execute(context);
// call the eventhandler to process
EventNavigationResult result = mEventHandler.handleEvent(context, request.getEvent());
// If redirected either during lifecycle or event handling merely return as new target is already encoded in response.
if (context.getResponseComplete()) return;
if (result != null)
{
context.getApplication().getNavigationHandler().handleNavigation(context, result.getFromAction(), result.getOutcome());
}
finalizeActionResponse(context);
// Process any Public Render parameter changes
processOutgoingPublicRenderParameters(context, request, response);
// Now check to see if we need to save the scope
// We don't save scope if the finalizeActionResponse detected
// a mode change
Boolean noScope = (Boolean) request.getAttribute(PortletExternalContextImpl.NO_SCOPE);
if (noScope == null || noScope.equals(Boolean.FALSE))
{
// If event occurred before an action we don't have acope yet
if (scopeId == null)
{
scopeId = initBridgeRequestScope(request, response);
// TBD: Mojarra 1.2_05 or later sets responseComplete if the restore occurs in
// a request that doesn't contain the isPostback marker (VIEW_STATE_PARAM).
// If we have no scopeId it means we received an event before the portlet
// was asked to render. In these versions the following render call will
// fail to render because there is no VIEW_STATE_PARAM. Should we artifucally
// set this here?
}
// Before preserving the request scope data in the bridge's
// request scope,
// put the Faces view into request scope. This is done because
// JSF 1.2 manages the tree save state opaquely exclusively in
// the render phase -- I.e. there is no JSF 1.2 way of having
// the
// bridge manually save and restore the view
saveFacesView(context);
// Because the portlet model doesn't execute its render phase
// within the same request scope but Faces does (assumes this),
// preserve the request scope data and the Faces view tree at
// RequestScope.
saveBridgeRequestScopeData(context, scopeId, preExistingAttributes);
}
}
catch (Exception e)
{
mPortletConfig.getPortletContext().log("Exception thrown in doFacesRequest:event", e);
if (!(e instanceof BridgeException))
{
e = new BridgeException(e);
}
throw (BridgeException) e;
}
finally
{
dumpScopeId(scopeId, "EVENT_PHASE");
if (lifecycle != null)
{
lifecycle.removePhaseListener(this);
}
if (context != null)
{
// remove the redirect attr so its not carried over to the