in trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/application/StateManagerImpl.java [652:865]
public UIViewRoot restoreView(
FacesContext context,
String viewId,
String renderKitId)
{
final ExternalContext extContext = context.getExternalContext();
// If we're being asked to execute a "return" event from, say, a dialog, always
// restore the "launch view", which was set over in the TrinidadFilter.
Map<String, Object> requestMap = extContext.getRequestMap();
UIViewRoot launchView = (UIViewRoot)
requestMap.remove(RequestContextImpl.LAUNCH_VIEW);
if (launchView != null)
{
TrinidadPhaseListener.markPostback(context);
return launchView;
}
final Object structure;
final Object state;
ResponseStateManager rsm = _getResponseStateManager(context, renderKitId);
if (_saveAsToken(context, true))
{
// we saved the token in the structure portion of the state, so retrieve the
// structure portion of the state to get the token.
String token = (String)rsm.getTreeStructureToRestore(context, viewId);
if (token == null)
{
_LOG.finest("No token in the request for view \"{0}\"; probably a first view.", viewId);
return null;
}
_LOG.finer("Restoring saved view state for token {0}", token);
// get the PageState for the token
PageState viewState = _getPageState(extContext, token);
if (viewState != null)
_updateRequestTokenForResponse(context, token);
RequestContext trinContext = RequestContext.getCurrentInstance();
// Make sure that if the view state is present, the cache still
// has the token, and vice versa
// NOTE: it's very important that we call through to the
// token cache here, not just inside the assert. If we don't,
// then we don't actually access the token, so it doesn't
// get bumped up to the front in the LRU Cache!
boolean isAvailable = _getViewCache(trinContext, extContext).isAvailable((String) token);
assert ((viewState != null) == isAvailable);
if (viewState == null)
{
_LOG.severe("CANNOT_FIND_SAVED_VIEW_STATE", token);
if(TokenCacheDebugUtils.debugTokenCache())
{
TokenCacheDebugUtils.startLog("Restore View");
String sessionId = "";
boolean isNewSession = false;
Object session = extContext.getSession(false);
if (session == null)
{
isNewSession = true;
}
else if (session instanceof HttpSession)
{
isNewSession = ((HttpSession)session).isNew();
sessionId = ((HttpSession)session).getId();
}
if (isNewSession)
{
TokenCacheDebugUtils.addToLog("The session is new. Session id = " + sessionId);
}
else
{
TokenCacheDebugUtils.addToLog("The session is NOT new. Session id = " + sessionId);
}
// get the state map
String subkey = _getViewCacheKey(extContext,
RequestContext.getCurrentInstance(),
_SUBKEY_SEPARATOR);
Map<String, PageState> stateMap = new SubKeyMap<PageState>(
extContext.getSessionMap(),
subkey);
// log what's currently in the state map
TokenCacheDebugUtils.logCacheInfo(stateMap, null, "token '" + token + "' not found");
_LOG.severe(TokenCacheDebugUtils.getLogString());
}
return null;
}
_LOG.fine("Successfully found view state for token {0}", token);
UIViewRoot root = viewState.popRoot(context); // bug 4712492
if (root != null)
{
_LOG.finer("UIViewRoot for token {0} already exists. Bypassing restoreState", token);
return root;
}
StateManagementStrategy sms = _getStateManagementStrategy(context, viewId);
if (sms!= null)
{
// TODO This is a hack because stateManagementStrategy doesn't take
// a state object as a param, instead it always asks the responseStateManager
// for the state, so push the state onto the request where the CoreResponseStateManager
// can return it. We will file a bug agains JSF 2.0 asking that the
// stateManagementStrategy deprecate the current restoreView method in favor of
// a restoreView method that takes state
try
{
requestMap.put(RESPONSE_STATE_MANAGER_STATE_KEY, viewState.getViewState(context));
root = sms.restoreView(context, viewId, renderKitId);
}
finally
{
requestMap.remove(RESPONSE_STATE_MANAGER_STATE_KEY);
}
return root;
}
else
{
Object[] stateArray = (Object[])viewState.getViewState(context);
structure = stateArray[0];
state = stateArray[1];
}
}
else
{
StateManagementStrategy sms = _getStateManagementStrategy(context, viewId);
if (sms!= null)
{
return sms.restoreView(context, viewId, renderKitId);
}
Object[] stateArray = (Object[])rsm.getState(context, viewId);
structure = stateArray[0];
state = stateArray[1];
}
if (structure == null)
{
UIViewRoot root = context.getViewRoot();
if (root == null && _needStructure(context))
{
_LOG.severe("NO_STRUCTURE_ROOT_AVAILABLE");
return null;
}
if (state != null)
root.processRestoreState(context, state);
return root;
}
else
{
if (!(structure instanceof Structure))
{
_LOG.severe("NO_STRUCTURE_AVAILABLE");
return null;
}
// OK, we've structure and state; let's see what we can do!
try
{
UIViewRoot root = (UIViewRoot)
((Structure) structure).createComponent();
if (state != null)
{
if (context.getViewRoot() == null)
{
context.setViewRoot(root);
}
root.processRestoreState(context, state);
}
_LOG.finer("Restored state for view \"{0}\"", viewId);
return root;
}
catch (ClassNotFoundException cnfe)
{
_LOG.severe(cnfe);
}
catch (InstantiationException ie)
{
_LOG.severe(ie);
}
catch (IllegalAccessException iae)
{
_LOG.severe(iae);
}
}
return null;
}