001    package com.mockrunner.mock.web;
002    
003    import java.util.ArrayList;
004    import java.util.Enumeration;
005    import java.util.HashMap;
006    import java.util.Iterator;
007    import java.util.List;
008    import java.util.Map;
009    import java.util.Vector;
010    
011    import javax.servlet.ServletContext;
012    import javax.servlet.http.HttpSession;
013    import javax.servlet.http.HttpSessionAttributeListener;
014    import javax.servlet.http.HttpSessionBindingEvent;
015    import javax.servlet.http.HttpSessionBindingListener;
016    import javax.servlet.http.HttpSessionContext;
017    
018    /**
019     * Mock implementation of <code>HttpSession</code>.
020     */
021    public class MockHttpSession implements HttpSession
022    {
023        private HashMap attributes;
024        private String sessionId;
025        private boolean isNew;
026        private boolean isValid;
027        private long creationTime;
028        private ServletContext servletContext;
029        private int maxInactiveInterval;
030        private List attributeListener;
031    
032        public MockHttpSession()
033        {
034            resetAll();
035        }
036        
037        /**
038         * Resets the state of this object to the default values
039         */
040        public synchronized void resetAll()
041        {
042            attributes = new HashMap();
043            isValid = true;
044            creationTime = System.currentTimeMillis();
045            sessionId = new Double(Math.random()).toString();
046            maxInactiveInterval = -1;
047            attributeListener = new ArrayList();
048        }
049    
050        public synchronized void addAttributeListener(HttpSessionAttributeListener listener)
051        {
052            attributeListener.add(listener);
053        }
054    
055        public synchronized void setupServletContext(ServletContext servletContext)
056        {
057            this.servletContext = servletContext;
058        }
059    
060        public synchronized ServletContext getServletContext()
061        {
062            return servletContext;
063        }
064        
065        public synchronized boolean isValid()
066        {
067            return isValid;
068        }
069    
070        public synchronized boolean isNew()
071        {
072            return isNew;
073        }
074    
075        public synchronized void setUpIsNew(boolean isNew)
076        {
077            this.isNew = isNew;
078        }
079    
080        public synchronized long getCreationTime()
081        {
082            return creationTime;
083        }
084    
085        public synchronized void invalidate()
086        {
087            if (!isValid) throw new IllegalStateException("session invalid");
088            isValid = false;
089            Map clone = new HashMap(attributes);
090            Iterator keys = clone.keySet().iterator();
091            while (keys.hasNext())
092            {
093                doRemoveAttribute((String)keys.next());
094            } 
095        }
096    
097        public synchronized String getId()
098        {
099            return sessionId;
100        }
101    
102        public synchronized Object getValue(String key)
103        {
104            if (!isValid) throw new IllegalStateException("session invalid");
105            return getAttribute(key);
106        }
107    
108        public synchronized String[] getValueNames()
109        {
110            if (!isValid) throw new IllegalStateException("session invalid");
111            Vector attKeys = new Vector(attributes.keySet());
112            return (String[]) attKeys.toArray();
113        }
114    
115        public synchronized void putValue(String key, Object value)
116        {
117            if (!isValid) throw new IllegalStateException("session invalid");
118            setAttribute(key, value);
119        }
120    
121        public synchronized void removeValue(String key)
122        {
123            if (!isValid) throw new IllegalStateException("session invalid");
124            removeAttribute(key);
125        }
126        
127        public synchronized void clearAttributes()
128        {
129            attributes.clear();
130        }
131    
132        public synchronized Object getAttribute(String key)
133        {
134            if (!isValid) throw new IllegalStateException("session invalid");
135            return attributes.get(key);
136        }
137    
138        public synchronized Enumeration getAttributeNames()
139        {
140            if (!isValid) throw new IllegalStateException("session invalid");
141            Vector attKeys = new Vector(attributes.keySet());
142            return attKeys.elements();
143        }
144    
145        public synchronized void removeAttribute(String key)
146        {
147            if (!isValid) throw new IllegalStateException("session invalid");
148            doRemoveAttribute(key);
149        }
150    
151        private void doRemoveAttribute(String key)
152        {
153            Object value = attributes.get(key);
154            attributes.remove(key);
155            if(null != value)
156            {
157                callValueUnboundMethod(key, value);
158                callAttributeListenersRemovedMethod(key, value);
159            }
160        }
161    
162        public synchronized void setAttribute(String key, Object value)
163        {
164            if (!isValid) throw new IllegalStateException("session invalid");
165            Object oldValue = attributes.get(key); 
166            if(null == value)
167            {
168                attributes.remove(key);
169            }
170            else
171            {
172                attributes.put(key, value);
173            }
174            handleBindingListenerCalls(key, value, oldValue);
175            handleAttributeListenerCalls(key, value, oldValue);
176        }
177    
178        private synchronized void handleBindingListenerCalls(String key, Object value, Object oldValue)
179        {
180            if(oldValue != null)
181            {
182                callValueUnboundMethod(key, oldValue);
183            }
184            if(value != null)
185            {
186                callValueBoundMethod(key, value);
187            }
188        }
189    
190        private synchronized void handleAttributeListenerCalls(String key, Object value, Object oldValue)
191        {
192            if(null != oldValue)
193            {
194                if(value != null)
195                {
196                    callAttributeListenersReplacedMethod(key, oldValue);
197                }
198                else
199                {
200                    callAttributeListenersRemovedMethod(key, oldValue);
201                }
202            }
203            else
204            {
205                if(value != null)
206                {
207                    callAttributeListenersAddedMethod(key, value);
208                }
209            
210            }
211        }
212        
213        public synchronized long getLastAccessedTime()
214        {
215            return System.currentTimeMillis();
216        }
217        
218        public synchronized void setMaxInactiveInterval(int maxInactiveInterval)
219        {
220            this.maxInactiveInterval = maxInactiveInterval;
221        }
222    
223        public synchronized int getMaxInactiveInterval()
224        {
225            return maxInactiveInterval;
226        }
227    
228        public synchronized HttpSessionContext getSessionContext()
229        {
230            return new MockSessionContext();
231        }
232        
233        private synchronized void callAttributeListenersAddedMethod(String key, Object value)
234        {
235            for(int ii = 0; ii < attributeListener.size(); ii++)
236            {
237                HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key, value);
238                ((HttpSessionAttributeListener)attributeListener.get(ii)).attributeAdded(event);
239            }
240        }
241    
242        private synchronized void callAttributeListenersReplacedMethod(String key, Object value)
243        {
244            for(int ii = 0; ii < attributeListener.size(); ii++)
245            {
246                HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key, value);
247                ((HttpSessionAttributeListener)attributeListener.get(ii)).attributeReplaced(event);
248            }
249        }
250    
251        private synchronized void callAttributeListenersRemovedMethod(String key, Object value)
252        {
253            for(int ii = 0; ii < attributeListener.size(); ii++)
254            {
255                HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key, value);
256                ((HttpSessionAttributeListener)attributeListener.get(ii)).attributeRemoved(event);
257            }
258        }
259    
260        private synchronized void callValueBoundMethod(String key, Object value)
261        {
262            if (value instanceof HttpSessionBindingListener)
263            {
264                HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key, value);
265                ((HttpSessionBindingListener) value).valueBound(event);
266            }
267        }
268    
269        private synchronized void callValueUnboundMethod(String key, Object value)
270        {
271            if (value instanceof HttpSessionBindingListener)
272            {
273                HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key, value);
274                ((HttpSessionBindingListener) value).valueUnbound(event);
275            }
276        }
277    }