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    
015    package org.apache.tapestry.record;
016    
017    import java.util.ArrayList;
018    import java.util.Collection;
019    import java.util.Collections;
020    import java.util.Iterator;
021    
022    import org.apache.hivemind.util.Defense;
023    import org.apache.tapestry.IRequestCycle;
024    import org.apache.tapestry.TapestryUtils;
025    import org.apache.tapestry.engine.ServiceEncoding;
026    import org.apache.tapestry.web.WebRequest;
027    import org.apache.tapestry.web.WebSession;
028    
029    /**
030     * The most basic {@link org.apache.tapestry.record.PropertyPersistenceStrategy}, which stores
031     * properties in the HttpSession as attributes.
032     * 
033     * @author Howard M. Lewis Ship
034     * @since 4.0
035     */
036    public class SessionPropertyPersistenceStrategy implements PropertyPersistenceStrategy
037    {
038        // Really, the name of the servlet; used as a prefix on all HttpSessionAttribute keys
039        // to keep things straight if multiple Tapestry apps are deployed
040        // in the same WAR.
041    
042        private String _applicationId;
043    
044        private WebRequest _request;
045    
046        public void store(String pageName, String idPath, String propertyName, Object newValue)
047        {
048            Defense.notNull(pageName, "pageName");
049            Defense.notNull(propertyName, "propertyName");
050    
051            WebSession session = _request.getSession(true);
052    
053            StringBuffer buffer = new StringBuffer();
054    
055            buffer.append(_applicationId);
056            buffer.append(",");
057            buffer.append(pageName);
058    
059            if (idPath != null)
060            {
061                buffer.append(",");
062                buffer.append(idPath);
063            }
064    
065            buffer.append(",");
066            buffer.append(propertyName);
067    
068            String key = buffer.toString();
069    
070            session.setAttribute(key, newValue);
071        }
072    
073        public Collection getStoredChanges(String pageName, IRequestCycle cycle)
074        {
075            Defense.notNull(pageName, "pageName");
076    
077            WebSession session = _request.getSession(false);
078    
079            if (session == null)
080                return Collections.EMPTY_LIST;
081    
082            Collection result = new ArrayList();
083    
084            String prefix = _applicationId + "," + pageName + ",";
085    
086            Iterator i = session.getAttributeNames().iterator();
087            while (i.hasNext())
088            {
089                String key = (String) i.next();
090    
091                if (key.startsWith(prefix))
092                {
093                    PropertyChange change = buildChange(key, session.getAttribute(key));
094    
095                    result.add(change);
096                }
097            }
098    
099            return result;
100        }
101    
102        private PropertyChange buildChange(String key, Object value)
103        {
104            String[] tokens = TapestryUtils.split(key);
105    
106            // Either app-name,page-name,id-path,property
107            // or app-name,page-name,property
108    
109            String idPath = (tokens.length == 4) ? tokens[2] : null;
110            String propertyName = tokens[tokens.length - 1];
111    
112            return new PropertyChangeImpl(idPath, propertyName, value);
113        }
114    
115        public void discardStoredChanges(String pageName, IRequestCycle cycle)
116        {
117            Defense.notNull(pageName, "pageName");
118    
119            WebSession session = _request.getSession(false);
120    
121            if (session == null)
122                return;
123    
124            String prefix = _applicationId + "," + pageName + ",";
125    
126            Iterator i = session.getAttributeNames().iterator();
127            while (i.hasNext())
128            {
129                String key = (String) i.next();
130    
131                if (key.startsWith(prefix))
132                    session.setAttribute(key, null);
133            }
134        }
135    
136        /**
137         * Does nothing; session persistence does not make use of query parameters.
138         */
139    
140        public void addParametersForPersistentProperties(ServiceEncoding encoding, IRequestCycle cycle, boolean post)
141        {
142        }
143    
144        public void setApplicationId(String applicationName)
145        {
146            _applicationId = applicationName;
147        }
148    
149        public void setRequest(WebRequest request)
150        {
151            _request = request;
152        }
153    }