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