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