in impl/src/main/java/org/apache/myfaces/application/viewstate/SerializedViewCollection.java [74:237]
public synchronized void put(FacesContext context, Object state,
SerializedViewKey key, SerializedViewKey previousRestoredKey, String viewScopeId,
Consumer<String> destroyCallback)
{
if (state == null)
{
state = EMPTY_STATES;
}
else if (state instanceof Object[] objects &&
objects.length == 2 &&
objects[0] == null &&
objects[1] == null)
{
// The generated state can be considered zero, set it as null
// into the map.
state = null;
}
if (_serializedViews.containsKey(key))
{
// Update the state, the viewScopeId does not change.
_serializedViews.put(key, state);
// Make sure the view is at the end of the discard queue
while (_keys.remove(key))
{
// do nothing
}
_keys.add(key);
return;
}
Integer maxCount = getNumberOfSequentialViewsInSession(context);
if (maxCount != null)
{
if (previousRestoredKey != null)
{
if (!_serializedViews.isEmpty())
{
_precedence.put(key, previousRestoredKey);
}
else
{
// Note when the session is invalidated, _serializedViews map is empty,
// but we could have a not null previousRestoredKey (the last one before
// invalidate the session), so we need to check that condition before
// set the precence. In that way, we ensure the precedence map will always
// have valid keys.
previousRestoredKey = null;
}
}
}
_serializedViews.put(key, state);
if (viewScopeId != null)
{
if (_viewScopeIds == null)
{
_viewScopeIds = new HashMap<>();
}
_viewScopeIds.put(key, viewScopeId);
if (_viewScopeIdCounts == null)
{
_viewScopeIdCounts = new HashMap<>();
}
Integer vscount = _viewScopeIdCounts.get(viewScopeId);
vscount = (vscount == null) ? 1 : vscount + 1;
_viewScopeIdCounts.put(viewScopeId, vscount);
}
while (_keys.remove(key))
{
// do nothing
}
_keys.add(key);
if (previousRestoredKey != null && maxCount != null && maxCount > 0)
{
int count = 0;
SerializedViewKey previousKey = key;
do
{
previousKey = _precedence.get(previousKey);
count++;
}
while (previousKey != null && count < maxCount);
if (previousKey != null)
{
SerializedViewKey keyToRemove = previousKey;
// In theory it should be only one key but just to be sure
// do it in a loop, but in this case if cache old views is on,
// put on that map.
do
{
while (_keys.remove(keyToRemove))
{
// do nothing
}
_serializedViews.remove(keyToRemove);
if (_viewScopeIds != null)
{
String oldViewScopeId = _viewScopeIds.remove(keyToRemove);
if (oldViewScopeId != null)
{
Integer vscount = _viewScopeIdCounts.get(oldViewScopeId);
vscount = vscount - 1;
if (vscount < 1)
{
_viewScopeIdCounts.remove(oldViewScopeId);
destroyCallback.accept(oldViewScopeId);
}
else
{
_viewScopeIdCounts.put(oldViewScopeId, vscount);
}
}
}
keyToRemove = _precedence.remove(keyToRemove);
}
while (keyToRemove != null);
}
}
int views = getNumberOfViewsInSession(context);
while (_keys.size() > views)
{
key = _keys.remove(0);
if (maxCount != null && maxCount > 0)
{
SerializedViewKey keyToRemove = key;
// Note in this case the key to delete is the oldest one,
// so it could be at least one precedence, but to be safe
// do it with a loop.
do
{
keyToRemove = _precedence.remove(keyToRemove);
}
while (keyToRemove != null);
}
_serializedViews.remove(key);
if (_viewScopeIds != null)
{
String oldViewScopeId = _viewScopeIds.remove(key);
if (oldViewScopeId != null)
{
Integer vscount = _viewScopeIdCounts.get(oldViewScopeId);
vscount = vscount - 1;
if (vscount < 1)
{
_viewScopeIdCounts.remove(oldViewScopeId);
destroyCallback.accept(oldViewScopeId);
}
else
{
_viewScopeIdCounts.put(oldViewScopeId, vscount);
}
}
}
}
}