1 /* 2 * Copyright 2002-2011 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.springframework.mock.web; 18 19 import java.io.Serializable; 20 import java.util.Enumeration; 21 import java.util.HashMap; 22 import java.util.Iterator; 23 import java.util.LinkedHashMap; 24 import java.util.Map; 25 import java.util.Vector; 26 import javax.servlet.ServletContext; 27 import javax.servlet.http.HttpSession; 28 import javax.servlet.http.HttpSessionBindingEvent; 29 import javax.servlet.http.HttpSessionBindingListener; 30 import javax.servlet.http.HttpSessionContext; 31 32 import org.springframework.util.Assert; 33 34 /** 35 * Mock implementation of the {@link javax.servlet.http.HttpSession} interface. 36 * 37 * <p>Compatible with Servlet 2.5 as well as Servlet 3.0. 38 * 39 * @author Juergen Hoeller 40 * @author Rod Johnson 41 * @author Mark Fisher 42 * @since 1.0.2 43 */ 44 @SuppressWarnings("deprecation") 45 public class MockHttpSession implements HttpSession { 46 47 private static int nextId = 1; 48 49 private final String id; 50 51 private final long creationTime = System.currentTimeMillis(); 52 53 private int maxInactiveInterval; 54 55 private long lastAccessedTime = System.currentTimeMillis(); 56 57 private final ServletContext servletContext; 58 59 private final Map<String, Object> attributes = new LinkedHashMap<String, Object>(); 60 61 private boolean invalid = false; 62 63 private boolean isNew = true; 64 65 66 /** 67 * Create a new MockHttpSession with a default {@link MockServletContext}. 68 * 69 * @see MockServletContext 70 */ MockHttpSession()71 public MockHttpSession() { 72 this(null); 73 } 74 75 /** 76 * Create a new MockHttpSession. 77 * 78 * @param servletContext the ServletContext that the session runs in 79 */ MockHttpSession(ServletContext servletContext)80 public MockHttpSession(ServletContext servletContext) { 81 this(servletContext, null); 82 } 83 84 /** 85 * Create a new MockHttpSession. 86 * 87 * @param servletContext the ServletContext that the session runs in 88 * @param id a unique identifier for this session 89 */ MockHttpSession(ServletContext servletContext, String id)90 public MockHttpSession(ServletContext servletContext, String id) { 91 this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); 92 this.id = (id != null ? id : Integer.toString(nextId++)); 93 } 94 getCreationTime()95 public long getCreationTime() { 96 return this.creationTime; 97 } 98 getId()99 public String getId() { 100 return this.id; 101 } 102 access()103 public void access() { 104 this.lastAccessedTime = System.currentTimeMillis(); 105 this.isNew = false; 106 } 107 getLastAccessedTime()108 public long getLastAccessedTime() { 109 return this.lastAccessedTime; 110 } 111 getServletContext()112 public ServletContext getServletContext() { 113 return this.servletContext; 114 } 115 setMaxInactiveInterval(int interval)116 public void setMaxInactiveInterval(int interval) { 117 this.maxInactiveInterval = interval; 118 } 119 getMaxInactiveInterval()120 public int getMaxInactiveInterval() { 121 return this.maxInactiveInterval; 122 } 123 getSessionContext()124 public HttpSessionContext getSessionContext() { 125 throw new UnsupportedOperationException("getSessionContext"); 126 } 127 getAttribute(String name)128 public Object getAttribute(String name) { 129 Assert.notNull(name, "Attribute name must not be null"); 130 return this.attributes.get(name); 131 } 132 getValue(String name)133 public Object getValue(String name) { 134 return getAttribute(name); 135 } 136 getAttributeNames()137 public Enumeration<String> getAttributeNames() { 138 return new Vector<String>(this.attributes.keySet()).elements(); 139 } 140 getValueNames()141 public String[] getValueNames() { 142 return this.attributes.keySet().toArray(new String[this.attributes.size()]); 143 } 144 setAttribute(String name, Object value)145 public void setAttribute(String name, Object value) { 146 Assert.notNull(name, "Attribute name must not be null"); 147 if (value != null) { 148 this.attributes.put(name, value); 149 if (value instanceof HttpSessionBindingListener) { 150 ((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value)); 151 } 152 } 153 else { 154 removeAttribute(name); 155 } 156 } 157 putValue(String name, Object value)158 public void putValue(String name, Object value) { 159 setAttribute(name, value); 160 } 161 removeAttribute(String name)162 public void removeAttribute(String name) { 163 Assert.notNull(name, "Attribute name must not be null"); 164 Object value = this.attributes.remove(name); 165 if (value instanceof HttpSessionBindingListener) { 166 ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); 167 } 168 } 169 removeValue(String name)170 public void removeValue(String name) { 171 removeAttribute(name); 172 } 173 174 /** 175 * Clear all of this session's attributes. 176 */ clearAttributes()177 public void clearAttributes() { 178 for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) { 179 Map.Entry<String, Object> entry = it.next(); 180 String name = entry.getKey(); 181 Object value = entry.getValue(); 182 it.remove(); 183 if (value instanceof HttpSessionBindingListener) { 184 ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); 185 } 186 } 187 } 188 invalidate()189 public void invalidate() { 190 this.invalid = true; 191 clearAttributes(); 192 } 193 isInvalid()194 public boolean isInvalid() { 195 return this.invalid; 196 } 197 setNew(boolean value)198 public void setNew(boolean value) { 199 this.isNew = value; 200 } 201 isNew()202 public boolean isNew() { 203 return this.isNew; 204 } 205 206 /** 207 * Serialize the attributes of this session into an object that can be 208 * turned into a byte array with standard Java serialization. 209 * 210 * @return a representation of this session's serialized state 211 */ serializeState()212 public Serializable serializeState() { 213 HashMap<String, Serializable> state = new HashMap<String, Serializable>(); 214 for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) { 215 Map.Entry<String, Object> entry = it.next(); 216 String name = entry.getKey(); 217 Object value = entry.getValue(); 218 it.remove(); 219 if (value instanceof Serializable) { 220 state.put(name, (Serializable) value); 221 } 222 else { 223 // Not serializable... Servlet containers usually automatically 224 // unbind the attribute in this case. 225 if (value instanceof HttpSessionBindingListener) { 226 ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); 227 } 228 } 229 } 230 return state; 231 } 232 233 /** 234 * Deserialize the attributes of this session from a state object created by 235 * {@link #serializeState()}. 236 * 237 * @param state a representation of this session's serialized state 238 */ 239 @SuppressWarnings("unchecked") deserializeState(Serializable state)240 public void deserializeState(Serializable state) { 241 Assert.isTrue(state instanceof Map, "Serialized state needs to be of type [java.util.Map]"); 242 this.attributes.putAll((Map<String, Object>) state); 243 } 244 245 } 246