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 = new ArrayList();
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            sessionCreated = true;
211            return session; 
212        }
213        
214        public HttpSession getSession(boolean create)
215        {
216            if(!create && !sessionCreated) return null;
217            return getSession();
218        }
219    
220        /**
221         * Sets the <code>HttpSession</code>.
222         * @param session the <code>HttpSession</code>
223         */
224        public void setSession(HttpSession session) 
225        {
226            this.session = session;   
227        }
228    
229        public RequestDispatcher getRequestDispatcher(String path)
230        {
231            RequestDispatcher dispatcher = (RequestDispatcher)requestDispatchers.get(path);
232            if(null == dispatcher)
233            {
234                dispatcher = new MockRequestDispatcher();
235                setRequestDispatcher(path, dispatcher);
236            }
237            return dispatcher;
238        }
239        
240        /**
241         * Returns the map of <code>RequestDispatcher</code> objects. The specified path
242         * maps to the corresponding <code>RequestDispatcher</code> object.
243         * @return the map of <code>RequestDispatcher</code> objects
244         */
245        public Map getRequestDispatcherMap()
246        {
247            return Collections.unmodifiableMap(requestDispatchers);
248        }
249        
250        /**
251         * Clears the map of <code>RequestDispatcher</code> objects. 
252         */
253        public void clearRequestDispatcherMap()
254        {
255            requestDispatchers.clear();
256        }
257        
258        /**
259         * Sets a <code>RequestDispatcher</code> that will be returned when calling
260         * {@link #getRequestDispatcher} with the specified path. If no <code>RequestDispatcher</code>
261         * is set for the specified path, {@link #getRequestDispatcher} automatically creates a
262         * new one.
263         * @param path the path for the <code>RequestDispatcher</code>
264         * @param dispatcher the <code>RequestDispatcher</code> object
265         */
266        public void setRequestDispatcher(String path, RequestDispatcher dispatcher)
267        {
268            if(dispatcher instanceof MockRequestDispatcher)
269            {
270                ((MockRequestDispatcher)dispatcher).setPath(path);
271            }
272            requestDispatchers.put(path, dispatcher);
273        }
274        
275        public Locale getLocale()
276        {
277            if(locales.size() < 1) return Locale.getDefault();
278            return (Locale)locales.get(0);
279        }
280    
281        public Enumeration getLocales()
282        {
283            return locales.elements();
284        }
285        
286        public void addLocale(Locale locale)
287        {
288            locales.add(locale);
289        }
290        
291        public void addLocales(List localeList)
292        {
293            locales.addAll(localeList);
294        }
295        
296        public String getMethod()
297        {
298            return method;
299        }
300    
301        public void setMethod(String method)
302        {
303            this.method = method;
304        }
305        
306        public String getAuthType()
307        {
308            return authType;
309        }
310        
311        public void setAuthType(String authType)
312        {
313            this.authType = authType;
314        }
315    
316        public long getDateHeader(String key)
317        {
318            String header = getHeader(key);
319            if(null == header) return -1;
320            try
321            {
322                Date dateValue = new SimpleDateFormat(WebConstants.DATE_FORMAT_HEADER, Locale.US).parse(header);
323                return dateValue.getTime();
324            }
325            catch (ParseException exc)
326            {
327                throw new IllegalArgumentException(exc.getMessage());
328            }
329        }
330    
331        public String getHeader(String key)
332        {
333            List headerList = (List)headers.get(key);
334            if(null == headerList || 0 == headerList.size()) return null;
335            return (String)headerList.get(0);
336        }
337    
338        public Enumeration getHeaderNames()
339        {
340            return new Vector(headers.keySet()).elements();
341        }
342    
343        public Enumeration getHeaders(String key)
344        {
345            List headerList = (List)headers.get(key);
346            if(null == headerList) return null;
347            return new Vector(headerList).elements();
348        }
349    
350        public int getIntHeader(String key)
351        {
352            String header = getHeader(key);
353            if(null == header) return -1;
354            return new Integer(header).intValue();
355        }
356        
357        public void addHeader(String key, String value)
358        {
359            List valueList = (List) headers.get(key);
360            if (null == valueList)
361            {
362                valueList = new ArrayList();
363                headers.put(key, valueList);
364            }
365            valueList.add(value);
366        }
367        
368        public void setHeader(String key, String value)
369        {
370            List valueList = new ArrayList();
371            headers.put(key, valueList);
372            valueList.add(value);
373        }
374        
375        public void clearHeaders()
376        {
377            headers.clear();
378        }
379        
380        public String getContextPath()
381        {
382            return contextPath;
383        }
384        
385        public void setContextPath(String contextPath)
386        {
387            this.contextPath = contextPath;
388        }
389        
390        public String getPathInfo()
391        {
392            return pathInfo;
393        }
394        
395        public void setPathInfo(String pathInfo)
396        {
397            this.pathInfo = pathInfo;
398        }
399        
400        public String getPathTranslated()
401        {
402            return pathTranslated;
403        }
404        
405        public void setPathTranslated(String pathTranslated)
406        {
407            this.pathTranslated = pathTranslated;
408        }
409        
410        public String getQueryString()
411        {
412            return queryString;
413        }
414        
415        public void setQueryString(String queryString)
416        {
417            this.queryString = queryString;
418        }
419        
420        public String getRequestURI()
421        {
422            return requestUri;
423        }
424        
425        public void setRequestURI(String requestUri)
426        {
427            this.requestUri = requestUri;
428        }
429        
430        public StringBuffer getRequestURL()
431        {
432            return requestUrl;
433        }
434        
435        public void setRequestURL(String requestUrl)
436        {
437            this.requestUrl = new StringBuffer(requestUrl);
438        }
439        
440        public String getServletPath()
441        {
442            return servletPath;
443        }
444        
445        public void setServletPath(String servletPath)
446        {
447            this.servletPath = servletPath;
448        }
449        
450        public Principal getUserPrincipal()
451        {
452            return principal;
453        }
454        
455        public void setUserPrincipal(Principal principal)
456        {
457            this.principal = principal;
458        }
459        
460        public String getRemoteUser()
461        {
462            return remoteUser;
463        }
464    
465        public void setRemoteUser(String remoteUser)
466        {
467            this.remoteUser = remoteUser;
468        }
469    
470        public Cookie[] getCookies()
471        {
472            return (Cookie[])cookies.toArray(new Cookie[cookies.size()]);
473        }
474        
475        public void addCookie(Cookie cookie)
476        {
477            cookies.add(cookie);
478        }
479    
480        public String getRequestedSessionId()
481        {
482            HttpSession session = getSession();
483            if(null == session) return null;
484            return session.getId();
485        }
486    
487        public boolean isRequestedSessionIdFromCookie()
488        {
489            return requestedSessionIdIsFromCookie;
490        }
491    
492        public boolean isRequestedSessionIdFromUrl()
493        {
494            return isRequestedSessionIdFromURL();
495        }
496    
497        public boolean isRequestedSessionIdFromURL()
498        {
499            return !requestedSessionIdIsFromCookie;
500        }
501        
502        public void setRequestedSessionIdFromCookie(boolean requestedSessionIdIsFromCookie)
503        {
504            this.requestedSessionIdIsFromCookie = requestedSessionIdIsFromCookie;
505        }
506    
507        public boolean isRequestedSessionIdValid()
508        {
509            HttpSession session = getSession();
510            if(null == session) return false;
511            return true;
512        }
513    
514        public boolean isUserInRole(String role)
515        {
516            return ((Boolean)roles.get(role)).booleanValue();
517        }
518        
519        public void setUserInRole(String role, boolean isInRole)
520        {
521            roles.put(role, new Boolean(isInRole));
522        }
523    
524        public String getCharacterEncoding()
525        {
526            return characterEncoding;
527        }
528        
529        public void setCharacterEncoding(String characterEncoding) throws UnsupportedEncodingException
530        {
531            this.characterEncoding = characterEncoding;
532        }
533    
534        public int getContentLength()
535        {
536            return contentLength;
537        }
538        
539        public void setContentLength(int contentLength)
540        {
541            this.contentLength = contentLength;
542        }
543    
544        public String getContentType()
545        {
546            return contentType;
547        }
548        
549        public void setContentType(String contentType)
550        {
551            this.contentType = contentType;
552        }
553    
554        public String getProtocol()
555        {
556            return protocol;
557        }
558        
559        public void setProtocol(String protocol)
560        {
561            this.protocol = protocol;
562        }
563        
564        public String getServerName()
565        {
566            return serverName;
567        }
568        
569        public void setServerName(String serverName)
570        {
571            this.serverName = serverName;
572        }
573        
574        public int getServerPort()
575        {
576            return serverPort;
577        }
578        
579        public void setServerPort(int serverPort)
580        {
581            this.serverPort = serverPort;
582        }
583        
584        public String getScheme()
585        {
586            return scheme;
587        }
588        
589        public void setScheme(String scheme)
590        {
591            this.scheme = scheme;
592        }
593        
594        public String getRemoteAddr()
595        {
596            return remoteAddr;
597        }
598        
599        public void setRemoteAddr(String remoteAddr)
600        {
601            this.remoteAddr = remoteAddr;
602        }
603        
604        public String getRemoteHost()
605        {
606            return remoteHost;
607        }
608        
609        public void setRemoteHost(String remoteHost)
610        {
611            this.remoteHost = remoteHost;
612        }
613    
614        public BufferedReader getReader() throws IOException
615        {
616            return new BufferedReader(new InputStreamReader(bodyContent));
617        }
618        
619        public ServletInputStream getInputStream() throws IOException
620        {
621            return bodyContent;
622        }
623        
624        public void setBodyContent(byte[] data)
625        {
626            bodyContent = new MockServletInputStream(data); 
627        }
628        
629        public void setBodyContent(String bodyContent)
630        {
631            String encoding = (null == characterEncoding) ? "ISO-8859-1" : characterEncoding;
632            try
633            {
634                setBodyContent(bodyContent.getBytes(encoding));
635            } 
636            catch(UnsupportedEncodingException exc)
637            {
638                throw new NestedApplicationException(exc);
639            }        
640        }
641    
642        public String getRealPath(String path)
643        {
644            HttpSession session = getSession();
645            if(null == session) return null;
646            return session.getServletContext().getRealPath(path);
647        } 
648        
649        public boolean isSecure()
650        {
651            String scheme = getScheme();
652            if(null == scheme) return false;
653            return scheme.equals("https");
654        }
655        
656        public String getLocalAddr()
657        {
658            return localAddr;
659        }
660        
661        public void setLocalAddr(String localAddr)
662        {
663            this.localAddr = localAddr;
664        }
665    
666        public String getLocalName()
667        {
668            return localName;
669        }
670        
671        public void setLocalName(String localName)
672        {
673            this.localName = localName;
674        }
675    
676        public int getLocalPort()
677        {
678            return localPort;
679        }
680        
681        public void setLocalPort(int localPort)
682        {
683            this.localPort = localPort;
684        }
685    
686        public int getRemotePort()
687        {
688            return remotePort;
689        }
690    
691        public void setRemotePort(int remotePort)
692        {
693            this.remotePort = remotePort;
694        }
695        
696        private void handleAttributeListenerCalls(String key, Object value, Object oldValue)
697        {
698            if(null != oldValue)
699            {
700                if(value != null)
701                {
702                    callAttributeListenersReplacedMethod(key, oldValue);
703                }
704                else
705                {
706                    callAttributeListenersRemovedMethod(key, oldValue);
707                }
708            }
709            else
710            {
711                if(value != null)
712                {
713                    callAttributeListenersAddedMethod(key, value);
714                }
715        
716            }
717        }
718        
719        private void callAttributeListenersAddedMethod(String key, Object value)
720        {
721            for(int ii = 0; ii < attributeListener.size(); ii++)
722            {
723                ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(getServletContext(), this, key, value);
724                ((ServletRequestAttributeListener)attributeListener.get(ii)).attributeAdded(event);
725            }
726        }
727        
728        private void callAttributeListenersReplacedMethod(String key, Object value)
729        {
730            for(int ii = 0; ii < attributeListener.size(); ii++)
731            {
732                ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(getServletContext(), this, key, value);
733                ((ServletRequestAttributeListener)attributeListener.get(ii)).attributeReplaced(event);
734            }
735        }
736    
737        private void callAttributeListenersRemovedMethod(String key, Object value)
738        {
739            for(int ii = 0; ii < attributeListener.size(); ii++)
740            {
741                ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(getServletContext(), this, key, value);
742                ((ServletRequestAttributeListener)attributeListener.get(ii)).attributeRemoved(event);
743            }
744        }
745        
746        private ServletContext getServletContext()
747        {
748            if(null == session) return new MockServletContext();
749            return session.getServletContext();
750        }
751    }