if (applicationViewCache == null)
{
assert(!dontSave);
TokenCache cache = _getViewCache(context);
assert(cache != null);
Map<String, Object> sessionMap = extContext.getSessionMap();
// Store bits of the session as subkeys off of the session
Map<String, PageState> stateMap = new SubKeyMap<PageState>(sessionMap,
_VIEW_CACHE_KEY + ".");
// Sadly, we can't save just a SerializedView, because we should
// save a serialized object, and SerializedView is a *non*-static
// inner class of StateManager
PageState pageState = new PageState(
context,
structure,
state,
// Save the view root into the page state as a transient
// if this feature has not been disabled
_useViewRootCache(context) ? root : null);
// clear out all of the previous PageStates' UIViewRoots and add this page
// state as an active page state. This is necessary to avoid UIViewRoots
// laying around if the user navigates off of a page using a GET
synchronized(extContext.getSession(true))
{
PageState activePageState = (PageState)sessionMap.get(_ACTIVE_PAGE_STATE_SESSION_KEY);
if (activePageState != null)
activePageState.clearViewRootState();
sessionMap.put(_ACTIVE_PAGE_STATE_SESSION_KEY, pageState);
}
String requestToken = _getRequestTokenForResponse(context);
// If we have a cached token that we want to reuse,
// and that token hasn't disappeared from the cache already
// (unlikely, but not impossible), use the stateMap directly
// without asking the cache for a new token
if ((requestToken != null) && cache.isAvailable(requestToken))
{
// NOTE: under *really* high pressure, the cache might
// have been emptied between the isAvailable() call and
// this put(). This seems sufficiently implausible to
// be worth punting on
stateMap.put(requestToken, pageState);
token = requestToken;
// NOTE 2: we have not pinned this reused state to any old state
// This is OK for current uses of pinning and state reuse,
// as pinning stays constant within a window, and we're not
// erasing pinning at all.
}
else
{
// See if we should pin this new state to any old state
String pinnedToken = (String)extContext.getRequestMap().get(_PINNED_STATE_TOKEN_KEY);
token = cache.addNewEntry(pageState,
stateMap,
pinnedToken);
}
}
// If we got the "applicationViewCache", we're using it.