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            attributes = new HashMap();
035            isValid = true;
036            creationTime = System.currentTimeMillis();
037            sessionId = new Double(Math.random()).toString();
038            maxInactiveInterval = -1;
039            attributeListener = new ArrayList();
040        }
041        
042        public synchronized void addAttributeListener(HttpSessionAttributeListener listener)
043        {
044            attributeListener.add(listener);
045        }
046    
047        public synchronized void setupServletContext(ServletContext servletContext)
048        {
049            this.servletContext = servletContext;
050        }
051    
052        public synchronized ServletContext getServletContext()
053        {
054            return servletContext;
055        }
056        
057        public synchronized boolean isValid()
058        {
059            return isValid;
060        }
061    
062        public synchronized boolean isNew()
063        {
064            return isNew;
065        }
066    
067        public synchronized void setUpIsNew(boolean isNew)
068        {
069            this.isNew = isNew;
070        }
071    
072        public synchronized long getCreationTime()
073        {
074            return creationTime;
075        }
076    
077        public synchronized void invalidate()
078        {
079            Map clone = new HashMap(attributes);
080            Iterator keys = clone.keySet().iterator();
081            while (keys.hasNext())
082            {
083                removeAttribute((String) keys.next());
084            }
085            isValid = false;
086        }
087    
088        public synchronized String getId()
089        {
090            return sessionId;
091        }
092    
093        public synchronized Object getValue(String key)
094        {
095            if (!isValid) throw new IllegalStateException("session invalid");
096            return getAttribute(key);
097        }
098    
099        public synchronized String[] getValueNames()
100        {
101            if (!isValid) throw new IllegalStateException("session invalid");
102            Vector attKeys = new Vector(attributes.keySet());
103            return (String[]) attKeys.toArray();
104        }
105    
106        public synchronized void putValue(String key, Object value)
107        {
108            if (!isValid) throw new IllegalStateException("session invalid");
109            setAttribute(key, value);
110        }
111    
112        public synchronized void removeValue(String key)
113        {
114            if (!isValid) throw new IllegalStateException("session invalid");
115            removeAttribute(key);
116        }
117        
118        public synchronized void clearAttributes()
119        {
120            attributes.clear();
121        }
122    
123        public synchronized Object getAttribute(String key)
124        {
125            if (!isValid) throw new IllegalStateException("session invalid");
126            return attributes.get(key);
127        }
128    
129        public synchronized Enumeration getAttributeNames()
130        {
131            if (!isValid) throw new IllegalStateException("session invalid");
132            Vector attKeys = new Vector(attributes.keySet());
133            return attKeys.elements();
134        }
135    
136        public synchronized void removeAttribute(String key)
137        {
138            if (!isValid) throw new IllegalStateException("session invalid");
139            Object value = attributes.get(key);
140            attributes.remove(key);
141            if(null != value)
142            {
143                callValueUnboundMethod(key, value);
144                callAttributeListenersRemovedMethod(key, value);
145            }
146        }
147    
148        public synchronized void setAttribute(String key, Object value)
149        {
150            if (!isValid) throw new IllegalStateException("session invalid");
151            Object oldValue = attributes.get(key); 
152            attributes.put(key, value);
153            handleBindingListenerCalls(key, value, oldValue);
154            handleAttributeListenerCalls(key, value, oldValue);
155        }
156    
157        private synchronized void handleBindingListenerCalls(String key, Object value, Object oldValue)
158        {
159            if(oldValue != null)
160            {
161                callValueUnboundMethod(key, oldValue);
162            }
163            if(value != null)
164            {
165                callValueBoundMethod(key, value);
166            }
167        }
168    
169        private synchronized void handleAttributeListenerCalls(String key, Object value, Object oldValue)
170        {
171            if(null != oldValue)
172            {
173                if(value != null)
174                {
175                    callAttributeListenersReplacedMethod(key, oldValue);
176                }
177                else
178                {
179                    callAttributeListenersRemovedMethod(key, oldValue);
180                }
181            }
182            else
183            {
184                if(value != null)
185                {
186                    callAttributeListenersAddedMethod(key, value);
187                }
188            
189            }
190        }
191        
192        public synchronized long getLastAccessedTime()
193        {
194            return System.currentTimeMillis();
195        }
196        
197        public synchronized void setMaxInactiveInterval(int maxInactiveInterval)
198        {
199            this.maxInactiveInterval = maxInactiveInterval;
200        }
201    
202        public synchronized int getMaxInactiveInterval()
203        {
204            return maxInactiveInterval;
205        }
206    
207        public synchronized HttpSessionContext getSessionContext()
208        {
209            return new MockSessionContext();
210        }
211        
212        private synchronized void callAttributeListenersAddedMethod(String key, Object value)
213        {
214            for(int ii = 0; ii < attributeListener.size(); ii++)
215            {
216                HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key, value);
217                ((HttpSessionAttributeListener)attributeListener.get(ii)).attributeAdded(event);
218            }
219        }
220    
221        private synchronized void callAttributeListenersReplacedMethod(String key, Object value)
222        {
223            for(int ii = 0; ii < attributeListener.size(); ii++)
224            {
225                HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key, value);
226                ((HttpSessionAttributeListener)attributeListener.get(ii)).attributeReplaced(event);
227            }
228        }
229    
230        private synchronized void callAttributeListenersRemovedMethod(String key, Object value)
231        {
232            for(int ii = 0; ii < attributeListener.size(); ii++)
233            {
234                HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key, value);
235                ((HttpSessionAttributeListener)attributeListener.get(ii)).attributeRemoved(event);
236            }
237        }
238    
239        private synchronized void callValueBoundMethod(String key, Object value)
240        {
241            if (value instanceof HttpSessionBindingListener)
242            {
243                HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key, value);
244                ((HttpSessionBindingListener) value).valueBound(event);
245            }
246        }
247    
248        private synchronized void callValueUnboundMethod(String key, Object value)
249        {
250            if (value instanceof HttpSessionBindingListener)
251            {
252                HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key, value);
253                ((HttpSessionBindingListener) value).valueUnbound(event);
254            }
255        }
256    }