1   package com.atlassian.core.filters;
2   
3   import org.apache.commons.collections.MultiMap;
4   import org.apache.commons.collections.MultiHashMap;
5   
6   import javax.servlet.http.HttpServletRequest;
7   import javax.servlet.http.HttpServletResponse;
8   import java.util.HashMap;
9   import java.util.Collection;
10  import java.util.Arrays;
11  import java.io.StringWriter;
12  import java.io.PrintWriter;
13  import java.io.IOException;
14  
15  import com.atlassian.core.test.util.DuckTypeProxy;
16  import com.atlassian.core.test.util.JavaBeanMethodHandler;
17  
18  public class ServletStubs
19  {
20      public static Request getRequestInstance()
21      {
22          return (Request) DuckTypeProxy.getProxy(Request.class,
23              Arrays.asList(new StubRequest()), new JavaBeanMethodHandler());
24      }
25  
26      public static Response getResponseInstance()
27      {
28          return (Response) DuckTypeProxy.getProxy(Response.class,
29              Arrays.asList(new StubResponse()), new JavaBeanMethodHandler());
30      }
31  
32      public interface Request extends HttpServletRequest
33      {
34          /**
35           * Sets the request URI which is returned by {@link #getRequestURI()}.
36           */
37          void setRequestURI(String requestUri);
38  
39          /**
40           * Sets a parameter which is returned by {@link #getParameter(String)} and {@link #getParameterValues(String)}.
41           */
42          void setParameter(String name, String value);
43  
44          /**
45           * Adds a parameter value which is returned by {@link #getParameter(String)} and {@link #getParameterValues(String)}.
46           */
47          void addParameter(String name, String value);
48  
49          /**
50           * Sets the parameter map to be returned by {@link #getParameterMap()}.
51           */
52          void setParameterMap(HashMap<String, String[]> parameterMap);
53      }
54  
55      /**
56       * This adds methods to {@link HttpServletResponse} to get and set values you can't otherwise
57       * change.
58       */
59      public interface Response extends HttpServletResponse
60      {
61          /**
62           * @return the value set by {@link #setContentType(String)}, or null if it has not been set.
63           */
64          String getContentType();
65  
66          /**
67           * Set the character encoding to be returned by {@link #getCharacterEncoding()}.
68           */
69          void setCharacterEncoding(String encoding);
70  
71          /**
72           * Return the header value set by {@link #setHeader(String, String)}, or null if the header has not been set.
73           * If {@link #addHeader(String, String)} has been called multiple times, only the first value is returned.
74           */
75          String getHeader(String headerName);
76  
77          /**
78           * Return the header value set by {@link #setDateHeader(String, long)}, or -1 if the header has not been set.
79           * If {@link #addDateHeader(String, long)} has been called multiple times, only the first value is returned.
80           */
81          long getDateHeader(String headerName);
82  
83          /**
84           * Returns all the data written to the response's {@link #getWriter()} as a String.
85           */
86          String getOutput();
87      }
88  
89      /**
90       * Stores headers in a multi-map and writes output to a StringWriter.
91       */
92      private static class StubResponse
93      {
94          private StringWriter output = new StringWriter();
95          private MultiMap headers = new MultiHashMap();
96  
97          public PrintWriter getWriter() throws IOException
98          {
99              return new PrintWriter(output);
100         }
101 
102         public String getOutput()
103         {
104             return output.toString();
105         }
106 
107         public void setDateHeader(String name, long date)
108         {
109             headers.remove(name);
110             headers.put(name, date);
111         }
112 
113         public void setHeader(String name, String value)
114         {
115             headers.remove(name);
116             headers.put(name, value);
117         }
118 
119         public void addHeader(String name, String value)
120         {
121             headers.put(name, value);
122         }
123 
124         public void addDateHeader(String name, long date)
125         {
126             headers.put(name, date);
127         }
128 
129         public String getHeader(String headerName)
130         {
131             Collection values = (Collection) headers.get(headerName);
132             return values == null ? null : (String) values.iterator().next(); // return the first value
133         }
134 
135         public long getDateHeader(String headerName)
136         {
137             Collection values = (Collection) headers.get(headerName);
138             return values == null ? -1 : (Long) values.iterator().next(); // return the first value
139         }
140     }
141 
142     private static class StubRequest
143     {
144         private MultiMap parameters = new MultiHashMap();
145 
146         public void setParameter(String name, String value)
147         {
148             parameters.remove(name);
149             parameters.put(name, value);
150         }
151 
152         public void addParameter(String name, String value)
153         {
154             parameters.put(name, value);
155         }
156 
157         public String getParameter(String name)
158         {
159             Collection values = (Collection) parameters.get(name);
160             return values == null ? null : (String) values.iterator().next(); // return the first value
161         }
162 
163         public String[] getParameterValues(String name)
164         {
165             //noinspection unchecked
166             Collection<String> values = (Collection<String>) parameters.get(name);
167             return values == null ? null : values.toArray(new String[values.size()]);
168         }
169     }
170 }