public synchronized void put()

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