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 }