001// Copyright 2005 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.tapestry.record;
016
017import java.util.ArrayList;
018import java.util.Collection;
019import java.util.Collections;
020
021import org.apache.hivemind.util.Defense;
022import org.apache.tapestry.engine.ServiceEncoding;
023import org.apache.tapestry.web.WebRequest;
024import org.apache.tapestry.web.WebSession;
025
026/**
027 * The most basic {@link org.apache.tapestry.record.PropertyPersistenceStrategy}, which stores
028 * properties in the HttpSession as attributes.
029 * 
030 * @author Howard M. Lewis Ship
031 * @since 4.0
032 */
033public class SessionPropertyPersistenceStrategy implements PropertyPersistenceStrategy
034{
035    public static final String STRATEGY_ID = "session";
036
037    // Really, the name of the servlet; used as a prefix on all HttpSessionAttribute keys
038    // to keep things straight if multiple Tapestry apps are deployed
039    // in the same WAR.
040
041    private String _applicationId;
042
043    private WebRequest _request;
044
045    public void store(String pageName, String idPath, String propertyName, Object newValue)
046    {
047        Defense.notNull(pageName, "pageName");
048        Defense.notNull(propertyName, "propertyName");
049
050        WebSession session = _request.getSession(true);
051
052        String attributeName = RecordUtils.buildChangeKey(
053                STRATEGY_ID,
054                _applicationId,
055                pageName,
056                idPath,
057                propertyName);
058
059        session.setAttribute(attributeName, newValue);
060    }
061
062    public Collection getStoredChanges(String pageName)
063    {
064        Defense.notNull(pageName, "pageName");
065
066        WebSession session = _request.getSession(false);
067
068        if (session == null)
069            return Collections.EMPTY_LIST;
070
071        final Collection result = new ArrayList();
072
073        WebSessionAttributeCallback callback = new WebSessionAttributeCallback()
074        {
075            public void handleAttribute(WebSession session, String name)
076            {
077                PropertyChange change = RecordUtils.buildChange(name, session.getAttribute(name));
078
079                result.add(change);
080            }
081        };
082
083        RecordUtils.iterateOverMatchingAttributes(
084                STRATEGY_ID,
085                _applicationId,
086                pageName,
087                session,
088                callback);
089
090        return result;
091    }
092
093    public void discardStoredChanges(String pageName)
094    {
095        WebSession session = _request.getSession(false);
096
097        if (session == null)
098            return;
099
100        WebSessionAttributeCallback callback = new WebSessionAttributeCallback()
101        {
102            public void handleAttribute(WebSession session, String name)
103            {
104                session.setAttribute(name, null);
105            }
106        };
107
108        RecordUtils.iterateOverMatchingAttributes(
109                STRATEGY_ID,
110                _applicationId,
111                pageName,
112                session,
113                callback);
114    }
115
116    /**
117     * Does nothing; session persistence does not make use of query parameters.
118     */
119
120    public void addParametersForPersistentProperties(ServiceEncoding encoding, boolean post)
121    {
122    }
123
124    public void setApplicationId(String applicationName)
125    {
126        _applicationId = applicationName;
127    }
128
129    public void setRequest(WebRequest request)
130    {
131        _request = request;
132    }
133}