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