001//  Copyright 2011 The Apache Software Foundation
002//
003//  Licensed under the Apache License, Version 2.0 (the "License");
004//  you may not use this file except in compliance with the License.
005//  You may obtain a copy of the License at
006//
007//  http://www.apache.org/licenses/LICENSE-2.0
008//
009//  Unless required by applicable law or agreed to in writing, software
010//  distributed under the License is distributed on an "AS IS" BASIS,
011//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012//  See the License for the specific language governing permissions and
013//  limitations under the License.
014
015package org.apache.tapestry5.internal.services;
016
017import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
018import org.apache.tapestry5.services.SessionPersistedObjectAnalyzer;
019
020import javax.servlet.http.HttpServletRequest;
021import javax.servlet.http.HttpSession;
022import java.util.Map;
023
024/**
025 * A thin wrapper around {@link javax.servlet.http.HttpSession}.
026 *
027 * @since 5.3
028 */
029public class ClusteredSessionImpl extends SessionImpl
030{
031    private final SessionPersistedObjectAnalyzer analyzer;
032
033    /**
034     * Cache of attribute objects read from, or written to, the real session.
035     * This is needed for end-of-request
036     * processing.
037     */
038    private final Map<String, Object> sessionAttributeCache = CollectionFactory.newMap();
039
040    public ClusteredSessionImpl(
041            HttpServletRequest request,
042            HttpSession session,
043            SessionPersistedObjectAnalyzer analyzer)
044    {
045        super(request, session);
046        this.analyzer = analyzer;
047    }
048
049    @Override
050    public Object getAttribute(String name)
051    {
052        Object result = super.getAttribute(name);
053
054        sessionAttributeCache.put(name, result);
055
056        return result;
057    }
058
059    public void setAttribute(String name, Object value)
060    {
061        super.setAttribute(name, value);
062
063        sessionAttributeCache.put(name, value);
064    }
065
066    public void invalidate()
067    {
068        super.invalidate();
069
070        sessionAttributeCache.clear();
071    }
072
073    public void restoreDirtyObjects()
074    {
075        if (isInvalidated()) return;
076
077        if (sessionAttributeCache.isEmpty()) return;
078
079        for (Map.Entry<String, Object> entry : sessionAttributeCache.entrySet())
080        {
081            String attributeName = entry.getKey();
082
083            Object attributeValue = entry.getValue();
084
085            if (attributeValue == null) continue;
086
087            if (analyzer.checkAndResetDirtyState(attributeValue))
088            {
089                super.setAttribute(attributeName, attributeValue);
090            }
091        }
092    }
093}