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    
015    package org.apache.tapestry5.internal.services;
016    
017    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
018    import org.apache.tapestry5.services.SessionPersistedObjectAnalyzer;
019    
020    import javax.servlet.http.HttpServletRequest;
021    import javax.servlet.http.HttpSession;
022    import java.util.Map;
023    
024    /**
025     * A thin wrapper around {@link javax.servlet.http.HttpSession}.
026     *
027     * @since 5.3
028     */
029    public 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    }