001    package com.mockrunner.mock.web;
002    
003    import java.io.BufferedReader;
004    import java.io.IOException;
005    import java.io.InputStreamReader;
006    import java.io.UnsupportedEncodingException;
007    import java.security.Principal;
008    import java.text.ParseException;
009    import java.text.SimpleDateFormat;
010    import java.util.ArrayList;
011    import java.util.Collections;
012    import java.util.Date;
013    import java.util.Enumeration;
014    import java.util.HashMap;
015    import java.util.List;
016    import java.util.Locale;
017    import java.util.Map;
018    import java.util.Vector;
019    
020    import javax.servlet.RequestDispatcher;
021    import javax.servlet.ServletContext;
022    import javax.servlet.ServletInputStream;
023    import javax.servlet.ServletRequestAttributeEvent;
024    import javax.servlet.ServletRequestAttributeListener;
025    import javax.servlet.http.Cookie;
026    import javax.servlet.http.HttpServletRequest;
027    import javax.servlet.http.HttpSession;
028    
029    import com.mockrunner.base.NestedApplicationException;
030    import com.mockrunner.util.common.CaseAwareMap;
031    
032    /**
033     * Mock implementation of <code>HttpServletRequest</code>.
034     */
035    public class MockHttpServletRequest implements HttpServletRequest
036    {
037        private Map attributes;
038        private Map parameters;
039        private Vector locales;
040        private Map requestDispatchers;
041        private HttpSession session;
042        private String method;
043        private String authType;
044        private Map headers;
045        private String contextPath;
046        private String pathInfo;
047        private String pathTranslated;
048        private String queryString;
049        private StringBuffer requestUrl;
050        private String requestUri;
051        private String servletPath;
052        private Principal principal;
053        private String remoteUser;
054        private boolean requestedSessionIdIsFromCookie;
055        private String protocol;
056        private String serverName;
057        private int serverPort;
058        private String scheme;
059        private String remoteHost;
060        private String remoteAddr;
061        private Map roles;
062        private String characterEncoding;
063        private int contentLength;
064        private String contentType;
065        private List cookies;
066        private MockServletInputStream bodyContent;
067        private String localAddr;
068        private String localName;
069        private int localPort;
070        private int remotePort;
071        private boolean sessionCreated;
072        private List attributeListener;
073        
074        public MockHttpServletRequest()
075        {
076            resetAll();
077        }
078    
079        /**
080         * Resets the state of this object to the default values
081         */
082        public void resetAll()
083        {
084            attributes = new HashMap();
085            parameters = new HashMap();
086            locales = new Vector();
087            requestDispatchers = new HashMap();
088            method = "GET";
089            headers = new CaseAwareMap();
090            requestedSessionIdIsFromCookie = true;
091            protocol = "HTTP/1.1";
092            serverName = "localhost";
093            serverPort = 8080;
094            scheme = "http";
095            remoteHost = "localhost";
096            remoteAddr = "127.0.0.1";
097            roles = new HashMap();
098            contentLength = -1;
099            cookies = null;
100            localAddr = "127.0.0.1";
101            localName = "localhost";
102            localPort = 8080;
103            remotePort = 5000;
104            sessionCreated = false;
105            attributeListener = new ArrayList();
106            bodyContent = new MockServletInputStream(new byte[0]);
107        }
108    
109        public void addAttributeListener(ServletRequestAttributeListener listener)
110        {
111            attributeListener.add(listener);
112        }
113        
114        public String getParameter(String key)
115        {
116            String[] values = getParameterValues(key);
117            if (null != values && 0 < values.length)
118            {
119                return values[0];
120            }
121            return null;
122        }
123        
124        /**
125         * Clears the parameters.
126         */
127        public void clearParameters()
128        {
129            parameters.clear();
130        }
131    
132        public String[] getParameterValues(String key)
133        {
134            return (String[])parameters.get(key);
135        }
136    
137        /**
138         * Adds a request multivalue parameter.
139         * @param key the parameter key
140         * @param values the parameters values
141         */
142        public void setupAddParameter(String key, String[] values)
143        {
144            parameters.put(key, values);
145        }
146    
147        /**
148         * Adds a request parameter.
149         * @param key the parameter key
150         * @param value the parameters value
151         */
152        public void setupAddParameter(String key, String value)
153        {
154            setupAddParameter(key, new String[] { value });
155        }
156    
157        public Enumeration getParameterNames()
158        {
159            Vector parameterKeys = new Vector(parameters.keySet());
160            return parameterKeys.elements();
161        }
162    
163        public Map getParameterMap()
164        {
165            return Collections.unmodifiableMap(parameters);
166        }
167        
168        public void clearAttributes()
169        {
170            attributes.clear();
171        }
172    
173        public Object getAttribute(String key)
174        {
175            return attributes.get(key);
176        }
177    
178        public Enumeration getAttributeNames()
179        {
180            Vector attKeys = new Vector(attributes.keySet());
181            return attKeys.elements();
182        }
183    
184        public void removeAttribute(String key)
185        {
186            Object value = attributes.get(key);
187            attributes.remove(key);
188            if(null != value)
189            {
190                callAttributeListenersRemovedMethod(key, value);
191            }
192        }
193    
194        public void setAttribute(String key, Object value)
195        {
196            Object oldValue = attributes.get(key);
197            if(null == value)
198            {
199                attributes.remove(key);
200            }
201            else
202            {
203                attributes.put(key, value);
204            }
205            handleAttributeListenerCalls(key, value, oldValue);
206        }
207        
208        public HttpSession getSession()
209        {
210            return getSession(true);
211        }
212        
213        public HttpSession getSession(boolean create)
214        {
215            if(!create && !sessionCreated) return null;
216            if(create)
217            {
218                sessionCreated = true;
219                if(session instanceof MockHttpSession)
220                {
221                    if(!((MockHttpSession)session).isValid())
222                    {
223                        ((MockHttpSession)session).resetAll();
224                    }
225                }
226            }
227            return session;
228        }
229    
230        /**
231         * Sets the <code>HttpSession</code>.
232         * @param session the <code>HttpSession</code>
233         */
234        public void setSession(HttpSession session) 
235        {
236            this.session = session;   
237        }
238    
239        public RequestDispatcher getRequestDispatcher(String path)
240        {
241            RequestDispatcher dispatcher = (RequestDispatcher)requestDispatchers.get(path);
242            if(null == dispatcher)
243            {
244                dispatcher = new MockRequestDispatcher();
245                setRequestDispatcher(path, dispatcher);
246            }
247            return dispatcher;
248        }
249        
250        /**
251         * Returns the map of <code>RequestDispatcher</code> objects. The specified path
252         * maps to the corresponding <code>RequestDispatcher</code> object.
253         * @return the map of <code>RequestDispatcher</code> objects
254         */
255        public Map getRequestDispatcherMap()
256        {
257            return Collections.unmodifiableMap(requestDispatchers);
258        }
259        
260        /**
261         * Clears the map of <code>RequestDispatcher</code> objects. 
262         */
263        public void clearRequestDispatcherMap()
264        {
265            requestDispatchers.clear();
266        }
267        
268        /**
269         * Sets a <code>RequestDispatcher</code> that will be returned when calling
270         * {@link #getRequestDispatcher} with the specified path. If no <code>RequestDispatcher</code>
271         * is set for the specified path, {@link #getRequestDispatcher} automatically creates a
272         * new one.
273         * @param path the path for the <code>RequestDispatcher</code>
274         * @param dispatcher the <code>RequestDispatcher</code> object
275         */
276        public void setRequestDispatcher(String path, RequestDispatcher dispatcher)
277        {
278            if(dispatcher instanceof MockRequestDispatcher)
279            {
280                ((MockRequestDispatcher)dispatcher).setPath(path);
281            }
282            requestDispatchers.put(path, dispatcher);
283        }
284        
285        public Locale getLocale()
286        {
287            if(locales.size() < 1) return Locale.getDefault();
288            return (Locale)locales.get(0);
289        }
290    
291        public Enumeration getLocales()
292        {
293            return locales.elements();
294        }
295        
296        public void addLocale(Locale locale)
297        {
298            locales.add(locale);
299        }
300        
301        public void addLocales(List localeList)
302        {
303            locales.addAll(localeList);
304        }
305        
306        public String getMethod()
307        {
308            return method;
309        }
310    
311        public void setMethod(String method)
312        {
313            this.method = method;
314        }
315        
316        public String getAuthType()
317        {
318            return authType;
319        }
320        
321        public void setAuthType(String authType)
322        {
323            this.authType = authType;
324        }
325    
326        public long getDateHeader(String key)
327        {
328            String header = getHeader(key);
329            if(null == header) return -1;
330            try
331            {
332                Date dateValue = new SimpleDateFormat(WebConstants.DATE_FORMAT_HEADER, Locale.US).parse(header);
333                return dateValue.getTime();
334            }
335            catch (ParseException exc)
336            {
337                throw new IllegalArgumentException(exc.getMessage());
338            }
339        }
340    
341        public String getHeader(String key)
342        {
343            List headerList = (List)headers.get(key);
344            if(null == headerList || 0 == headerList.size()) return null;
345            return (String)headerList.get(0);
346        }
347    
348        public Enumeration getHeaderNames()
349        {
350            return new Vector(headers.keySet()).elements();
351        }
352    
353        public Enumeration getHeaders(String key)
354        {
355            List headerList = (List)headers.get(key);
356            if(null == headerList) return null;
357            return new Vector(headerList).elements();
358        }
359    
360        public int getIntHeader(String key)
361        {
362            String header = getHeader(key);
363            if(null == header) return -1;
364            return new Integer(header).intValue();
365        }
366        
367        public void addHeader(String key, String value)
368        {
369            List valueList = (List) headers.get(key);
370            if (null == valueList)
371            {
372                valueList = new ArrayList();
373                headers.put(key, valueList);
374            }
375            valueList.add(value);
376        }
377        
378        public void setHeader(String key, String value)
379        {
380            List valueList = new ArrayList();
381            headers.put(key, valueList);
382            valueList.add(value);
383        }
384        
385        public void clearHeaders()
386        {
387            headers.clear();
388        }
389        
390        public String getContextPath()
391        {
392            return contextPath;
393        }
394        
395        public void setContextPath(String contextPath)
396        {
397            this.contextPath = contextPath;
398        }
399        
400        public String getPathInfo()
401        {
402            return pathInfo;
403        }
404        
405        public void setPathInfo(String pathInfo)
406        {
407            this.pathInfo = pathInfo;
408        }
409        
410        public String getPathTranslated()
411        {
412            return pathTranslated;
413        }
414        
415        public void setPathTranslated(String pathTranslated)
416        {
417            this.pathTranslated = pathTranslated;
418        }
419        
420        public String getQueryString()
421        {
422            return queryString;
423        }
424        
425        public void setQueryString(String queryString)
426        {
427            this.queryString = queryString;
428        }
429        
430        public String getRequestURI()
431        {
432            return requestUri;
433        }
434        
435        public void setRequestURI(String requestUri)
436        {
437            this.requestUri = requestUri;
438        }
439        
440        public StringBuffer getRequestURL()
441        {
442            return requestUrl;
443        }
444        
445        public void setRequestURL(String requestUrl)
446        {
447            this.requestUrl = new StringBuffer(requestUrl);
448        }
449        
450        public String getServletPath()
451        {
452            return servletPath;
453        }
454        
455        public void setServletPath(String servletPath)
456        {
457            this.servletPath = servletPath;
458        }
459        
460        public Principal getUserPrincipal()
461        {
462            return principal;
463        }
464        
465        public void setUserPrincipal(Principal principal)
466        {
467            this.principal = principal;
468        }
469        
470        public String getRemoteUser()
471        {
472            return remoteUser;
473        }
474    
475        public void setRemoteUser(String remoteUser)
476        {
477            this.remoteUser = remoteUser;
478        }
479    
480        public Cookie[] getCookies()
481        {
482            if(null == cookies) return null;
483            return (Cookie[])cookies.toArray(new Cookie[cookies.size()]);
484        }
485        
486        public void addCookie(Cookie cookie)
487        {
488            if(null == cookies)
489            {
490                cookies = new ArrayList();
491            }
492            cookies.add(cookie);
493        }
494    
495        public String getRequestedSessionId()
496        {
497            HttpSession session = getSession();
498            if(null == session) return null;
499            return session.getId();
500        }
501    
502        public boolean isRequestedSessionIdFromCookie()
503        {
504            return requestedSessionIdIsFromCookie;
505        }
506    
507        public boolean isRequestedSessionIdFromUrl()
508        {
509            return isRequestedSessionIdFromURL();
510        }
511    
512        public boolean isRequestedSessionIdFromURL()
513        {
514            return !requestedSessionIdIsFromCookie;
515        }
516        
517        public void setRequestedSessionIdFromCookie(boolean requestedSessionIdIsFromCookie)
518        {
519            this.requestedSessionIdIsFromCookie = requestedSessionIdIsFromCookie;
520        }
521    
522        public boolean isRequestedSessionIdValid()
523        {
524            HttpSession session = getSession();
525            if(null == session) return false;
526            return true;
527        }
528    
529        public boolean isUserInRole(String role)
530        {
531            if(!roles.containsKey(role)) return false;
532            return ((Boolean)roles.get(role)).booleanValue();
533        }
534        
535        public void setUserInRole(String role, boolean isInRole)
536        {
537            roles.put(role, new Boolean(isInRole));
538        }
539    
540        public String getCharacterEncoding()
541        {
542            return characterEncoding;
543        }
544        
545        public void setCharacterEncoding(String characterEncoding) throws UnsupportedEncodingException
546        {
547            this.characterEncoding = characterEncoding;
548        }
549    
550        public int getContentLength()
551        {
552            return contentLength;
553        }
554        
555        public void setContentLength(int contentLength)
556        {
557            this.contentLength = contentLength;
558        }
559    
560        public String getContentType()
561        {
562            return contentType;
563        }
564        
565        public void setContentType(String contentType)
566        {
567            this.contentType = contentType;
568        }
569    
570        public String getProtocol()
571        {
572            return protocol;
573        }
574        
575        public void setProtocol(String protocol)
576        {
577            this.protocol = protocol;
578        }
579        
580        public String getServerName()
581        {
582            return serverName;
583        }
584        
585        public void setServerName(String serverName)
586        {
587            this.serverName = serverName;
588        }
589        
590        public int getServerPort()
591        {
592            return serverPort;
593        }
594        
595        public void setServerPort(int serverPort)
596        {
597            this.serverPort = serverPort;
598        }
599        
600        public String getScheme()
601        {
602            return scheme;
603        }
604        
605        public void setScheme(String scheme)
606        {
607            this.scheme = scheme;
608        }
609        
610        public String getRemoteAddr()
611        {
612            return remoteAddr;
613        }
614        
615        public void setRemoteAddr(String remoteAddr)
616        {
617            this.remoteAddr = remoteAddr;
618        }
619        
620        public String getRemoteHost()
621        {
622            return remoteHost;
623        }
624        
625        public void setRemoteHost(String remoteHost)
626        {
627            this.remoteHost = remoteHost;
628        }
629    
630        public BufferedReader getReader() throws IOException
631        {
632            return new BufferedReader(new InputStreamReader(bodyContent));
633        }
634        
635        public ServletInputStream getInputStream() throws IOException
636        {
637            return bodyContent;
638        }
639        
640        public void setBodyContent(byte[] data)
641        {
642            bodyContent = new MockServletInputStream(data); 
643        }
644        
645        public void setBodyContent(String bodyContent)
646        {
647            String encoding = (null == characterEncoding) ? "ISO-8859-1" : characterEncoding;
648            try
649            {
650                setBodyContent(bodyContent.getBytes(encoding));
651            } 
652            catch(UnsupportedEncodingException exc)
653            {
654                throw new NestedApplicationException(exc);
655            }        
656        }
657    
658        public String getRealPath(String path)
659        {
660            HttpSession session = getSession();
661            if(null == session) return null;
662            return session.getServletContext().getRealPath(path);
663        } 
664        
665        public boolean isSecure()
666        {
667            String scheme = getScheme();
668            if(null == scheme) return false;
669            return scheme.equals("https");
670        }
671        
672        public String getLocalAddr()
673        {
674            return localAddr;
675        }
676        
677        public void setLocalAddr(String localAddr)
678        {
679            this.localAddr = localAddr;
680        }
681    
682        public String getLocalName()
683        {
684            return localName;
685        }
686        
687        public void setLocalName(String localName)
688        {
689            this.localName = localName;
690        }
691    
692        public int getLocalPort()
693        {
694            return localPort;
695        }
696        
697        public void setLocalPort(int localPort)
698        {
699            this.localPort = localPort;
700        }
701    
702        public int getRemotePort()
703        {
704            return remotePort;
705        }
706    
707        public void setRemotePort(int remotePort)
708        {
709            this.remotePort = remotePort;
710        }
711        
712        private void handleAttributeListenerCalls(String key, Object value, Object oldValue)
713        {
714            if(null != oldValue)
715            {
716                if(value != null)
717                {
718                    callAttributeListenersReplacedMethod(key, oldValue);
719                }
720                else
721                {
722                    callAttributeListenersRemovedMethod(key, oldValue);
723                }
724            }
725            else
726            {
727                if(value != null)
728                {
729                    callAttributeListenersAddedMethod(key, value);
730                }
731        
732            }
733        }
734        
735        private void callAttributeListenersAddedMethod(String key, Object value)
736        {
737            for(int ii = 0; ii < attributeListener.size(); ii++)
738            {
739                ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(getServletContext(), this, key, value);
740                ((ServletRequestAttributeListener)attributeListener.get(ii)).attributeAdded(event);
741            }
742        }
743        
744        private void callAttributeListenersReplacedMethod(String key, Object value)
745        {
746            for(int ii = 0; ii < attributeListener.size(); ii++)
747            {
748                ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(getServletContext(), this, key, value);
749                ((ServletRequestAttributeListener)attributeListener.get(ii)).attributeReplaced(event);
750            }
751        }
752    
753        private void callAttributeListenersRemovedMethod(String key, Object value)
754        {
755            for(int ii = 0; ii < attributeListener.size(); ii++)
756            {
757                ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(getServletContext(), this, key, value);
758                ((ServletRequestAttributeListener)attributeListener.get(ii)).attributeRemoved(event);
759            }
760        }
761        
762        private ServletContext getServletContext()
763        {
764            if(null == session) return new MockServletContext();
765            return session.getServletContext();
766        }
767    }