    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    }