001    package com.mockrunner.mock.web;
002    
003    import java.io.ByteArrayInputStream;
004    import java.io.InputStream;
005    import java.net.MalformedURLException;
006    import java.net.URL;
007    import java.util.ArrayList;
008    import java.util.Collection;
009    import java.util.Collections;
010    import java.util.Enumeration;
011    import java.util.HashMap;
012    import java.util.HashSet;
013    import java.util.List;
014    import java.util.Map;
015    import java.util.Set;
016    import java.util.Vector;
017    
018    import javax.servlet.RequestDispatcher;
019    import javax.servlet.Servlet;
020    import javax.servlet.ServletContext;
021    import javax.servlet.ServletContextAttributeEvent;
022    import javax.servlet.ServletContextAttributeListener;
023    import javax.servlet.ServletException;
024    
025    import com.mockrunner.util.common.StreamUtil;
026    
027    /**
028     * Mock implementation of <code>ServletContext</code>.
029     */
030    public class MockServletContext implements ServletContext
031    {
032        private Map attributes;
033        private Map requestDispatchers;
034        private Map contexts;
035        private Map initParameters;
036        private Map mimeTypes;
037        private Map realPaths;
038        private Map resources;
039        private Map resourcePaths;
040        private Map resourceStreams;
041        private String servletContextName;
042        private String contextPath;
043        private List attributeListener;
044        
045        public MockServletContext()
046        {
047            resetAll();
048        }
049        
050        /**
051         * Resets the state of this object to the default values
052         */
053        public synchronized void resetAll()
054        {
055            attributes = new HashMap();
056            requestDispatchers = new HashMap();
057            contexts = new HashMap();
058            initParameters = new HashMap();
059            mimeTypes = new HashMap();
060            realPaths = new HashMap();
061            resources = new HashMap();
062            resourcePaths = new HashMap();
063            resourceStreams = new HashMap();
064            attributeListener = new ArrayList();
065        }
066    
067        public synchronized void addAttributeListener(ServletContextAttributeListener listener)
068        {
069            attributeListener.add(listener);
070        }
071        
072        public synchronized void clearAttributes()
073        {
074            attributes.clear();
075        }
076            
077        public synchronized Object getAttribute(String key)
078        {
079            return attributes.get(key);
080        }
081    
082        public synchronized Enumeration getAttributeNames()
083        {
084            Vector attKeys = new Vector(attributes.keySet());
085            return attKeys.elements();
086        }
087    
088        public synchronized void removeAttribute(String key)
089        {
090            Object value = attributes.get(key);
091            attributes.remove(key);
092            if(null != value)
093            {
094                callAttributeListenersRemovedMethod(key, value);
095            }
096        }
097    
098        public synchronized void setAttribute(String key, Object value)
099        {
100            Object oldValue = attributes.get(key);
101            if(null == value)
102            {
103                attributes.remove(key);
104            }
105            else
106            {
107                attributes.put(key, value);
108            }
109            handleAttributeListenerCalls(key, value, oldValue);
110        }
111        
112        public synchronized RequestDispatcher getNamedDispatcher(String name)
113        {
114            return getRequestDispatcher(name);
115        }
116    
117        public synchronized RequestDispatcher getRequestDispatcher(String path)
118        {
119            RequestDispatcher dispatcher = (RequestDispatcher)requestDispatchers.get(path);
120            if(null == dispatcher)
121            {
122                dispatcher = new MockRequestDispatcher();
123                setRequestDispatcher(path, dispatcher);
124            }
125            return dispatcher;
126        }
127        
128        /**
129         * Returns the map of <code>RequestDispatcher</code> objects. The specified path
130         * maps to the corresponding <code>RequestDispatcher</code> object.
131         * @return the map of <code>RequestDispatcher</code> objects
132         */
133        public synchronized Map getRequestDispatcherMap()
134        {
135            return Collections.unmodifiableMap(requestDispatchers);
136        }
137        
138        /**
139         * Clears the map of <code>RequestDispatcher</code> objects. 
140         */
141        public synchronized void clearRequestDispatcherMap()
142        {
143            requestDispatchers.clear();
144        }
145        
146        /**
147         * Sets a <code>RequestDispatcher</code> that will be returned when calling
148         * {@link #getRequestDispatcher} or {@link #getNamedDispatcher}
149         * with the specified path or name.
150         * If no <code>RequestDispatcher</code>
151         * is set for the specified path, {@link #getRequestDispatcher} and
152         * {@link #getNamedDispatcher} automatically create a new one.
153         * @param path the path for the <code>RequestDispatcher</code>
154         * @param dispatcher the <code>RequestDispatcher</code> object
155         */
156        public synchronized void setRequestDispatcher(String path, RequestDispatcher dispatcher)
157        {
158            if(dispatcher instanceof MockRequestDispatcher)
159            {
160                ((MockRequestDispatcher)dispatcher).setPath(path);
161            }
162            requestDispatchers.put(path, dispatcher);
163        }
164        
165        public synchronized ServletContext getContext(String url)
166        {
167            return (ServletContext)contexts.get(url);
168        }
169        
170        /**
171         * Sets a <code>ServletContext</code> that will be returned 
172         * when calling {@link #getContext}
173         * @param url the URL
174         * @param context the <code>ServletContext</code>
175         */
176        public synchronized void setContext(String url, ServletContext context)
177        {
178            contexts.put(url, context);
179        }
180        
181        /**
182         * Clears the init parameters.
183         */
184        public synchronized void clearInitParameters()
185        {
186            initParameters.clear();
187        }
188    
189        public synchronized String getInitParameter(String name)
190        {
191            return (String)initParameters.get(name);
192        }
193        
194        /**
195         * Sets an init parameter.
196         * @param name the name
197         * @param value the value
198         */
199        public synchronized void setInitParameter(String name, String value) 
200        {
201            initParameters.put(name, value);
202        }
203        
204        /**
205         * Sets several init parameters.
206         * @param parameters the parameter map
207         */
208        public synchronized void setInitParameters(Map parameters) 
209        {
210            initParameters.putAll(parameters);
211        }
212    
213        public synchronized Enumeration getInitParameterNames()
214        {
215            return new Vector(initParameters.keySet()).elements();
216        }
217    
218        public synchronized int getMajorVersion()
219        {
220            return 2;
221        }
222        
223        public synchronized int getMinorVersion()
224        {
225            return 3;
226        }
227    
228        public synchronized String getMimeType(String file)
229        {
230            return (String)mimeTypes.get(file);
231        }
232        
233        public synchronized void setMimeType(String file, String type)
234        {
235            mimeTypes.put(file, type);
236        }
237    
238        public synchronized String getRealPath(String path)
239        {
240            return (String)realPaths.get(path);
241        }
242        
243        public synchronized void setRealPath(String path, String realPath)
244        {
245            realPaths.put(path, realPath);
246        }
247    
248        public synchronized URL getResource(String path) throws MalformedURLException
249        {
250            return (URL)resources.get(path);
251        }
252        
253        public synchronized void setResource(String path, URL url)
254        {
255            resources.put(path, url);
256        }
257    
258        public synchronized InputStream getResourceAsStream(String path)
259        {
260            byte[] data = (byte[])resourceStreams.get(path);
261            if(null == data) return null;
262            return new ByteArrayInputStream(data);
263        }
264        
265        public synchronized void setResourceAsStream(String path, InputStream inputStream) 
266        { 
267            setResourceAsStream(path, StreamUtil.getStreamAsByteArray(inputStream)); 
268        }
269        
270        public synchronized void setResourceAsStream(String path, byte[] data)
271        {
272            byte[] copy = (byte[])data.clone();
273            resourceStreams.put(path, copy);
274        }
275    
276        public synchronized Set getResourcePaths(String path)
277        {
278            Set set = (Set)resourcePaths.get(path);
279            if(null == set) return null;
280            return Collections.unmodifiableSet(set);
281        }
282        
283        public synchronized void addResourcePaths(String path, Collection pathes)
284        {
285            Set set = (Set)resourcePaths.get(path);
286            if(null == set)
287            {
288                set = new HashSet();
289                resourcePaths.put(path, set);
290            }
291            set.addAll(pathes);
292        }
293        
294        public synchronized void addResourcePath(String path, String resourcePath)
295        {
296            ArrayList list = new ArrayList();
297            list.add(resourcePath);
298            addResourcePaths(path, list);
299        }
300    
301        public synchronized String getServerInfo()
302        {
303            return "Mockrunner Server";
304        }
305    
306        public synchronized Servlet getServlet(String arg0) throws ServletException
307        {
308            return null;
309        }
310    
311        public synchronized String getServletContextName()
312        {
313            return servletContextName;
314        }
315        
316        public synchronized void setServletContextName(String servletContextName)
317        {
318            this.servletContextName = servletContextName;
319        }
320    
321        public String getContextPath()
322        {
323            return contextPath;
324        }
325    
326        public void setContextPath(String contextPath)
327        {
328            this.contextPath = contextPath;
329        }
330    
331        public synchronized Enumeration getServletNames()
332        {
333            return new Vector().elements();
334        }
335    
336        public synchronized Enumeration getServlets()
337        {
338            return new Vector().elements();
339        }
340    
341        public synchronized void log(Exception exc, String message)
342        {
343    
344        }
345    
346        public synchronized void log(String message, Throwable exc)
347        {
348    
349        }
350    
351        public synchronized void log(String message)
352        {
353    
354        }
355        
356        private synchronized void handleAttributeListenerCalls(String key, Object value, Object oldValue)
357        {
358            if(null != oldValue)
359            {
360                if(value != null)
361                {
362                    callAttributeListenersReplacedMethod(key, oldValue);
363                }
364                else
365                {
366                    callAttributeListenersRemovedMethod(key, oldValue);
367                }
368            }
369            else
370            {
371                if(value != null)
372                {
373                    callAttributeListenersAddedMethod(key, value);
374                }
375        
376            }
377        }
378        
379        private synchronized void callAttributeListenersAddedMethod(String key, Object value)
380        {
381            for(int ii = 0; ii < attributeListener.size(); ii++)
382            {
383                ServletContextAttributeEvent event = new ServletContextAttributeEvent(this, key, value);
384                ((ServletContextAttributeListener)attributeListener.get(ii)).attributeAdded(event);
385            }
386        }
387    
388        private synchronized void callAttributeListenersReplacedMethod(String key, Object value)
389        {
390            for(int ii = 0; ii < attributeListener.size(); ii++)
391            {
392                ServletContextAttributeEvent event = new ServletContextAttributeEvent(this, key, value);
393                ((ServletContextAttributeListener)attributeListener.get(ii)).attributeReplaced(event);
394            }
395        }
396    
397        private synchronized void callAttributeListenersRemovedMethod(String key, Object value)
398        {
399            for(int ii = 0; ii < attributeListener.size(); ii++)
400            {
401                ServletContextAttributeEvent event = new ServletContextAttributeEvent(this, key, value);
402                ((ServletContextAttributeListener)attributeListener.get(ii)).attributeRemoved(event);
403            }
404        }
405    }