View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.commons.jcs3.jcache.extras.web;
20  
21  import java.io.IOException;
22  import java.io.OutputStream;
23  import java.io.OutputStreamWriter;
24  import java.io.PrintWriter;
25  import java.io.Serializable;
26  import java.util.ArrayList;
27  import java.util.Collection;
28  import java.util.LinkedList;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.TreeMap;
32  import java.util.concurrent.CopyOnWriteArraySet;
33  import javax.servlet.ServletOutputStream;
34  import javax.servlet.http.Cookie;
35  import javax.servlet.http.HttpServletResponse;
36  import javax.servlet.http.HttpServletResponseWrapper;
37  
38  public class InMemoryResponse extends HttpServletResponseWrapper implements Serializable
39  {
40      private final OutputStream buffer;
41  
42      private final Collection<Cookie> cookies = new CopyOnWriteArraySet<>();
43      private final Map<String, List<Serializable>> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
44      private int status = SC_OK;
45      private String contentType;
46      private PrintWriter writer;
47      private int contentLength;
48  
49      public InMemoryResponse(final HttpServletResponse response, final OutputStream baos)
50      {
51          super(response);
52          this.buffer = baos;
53      }
54  
55      private List<Serializable> ensureHeaderExists(final String s)
56      {
57          return headers.computeIfAbsent(s, k -> new LinkedList<>());
58      }
59  
60      @Override
61      public void addCookie(final Cookie cookie)
62      {
63          super.addCookie(cookie);
64          cookies.add(cookie);
65      }
66  
67      @Override
68      public void addDateHeader(final String s, final long l)
69      {
70          super.addDateHeader(s, l);
71          ensureHeaderExists(s).add(l);
72      }
73  
74      @Override
75      public void addHeader(final String s, final String s2)
76      {
77          super.addHeader(s, s2);
78          ensureHeaderExists(s).add(s2);
79      }
80  
81      @Override
82      public void addIntHeader(final String s, final int i)
83      {
84          super.addIntHeader(s, i);
85          ensureHeaderExists(s).add(i);
86      }
87  
88      @Override
89      public boolean containsHeader(final String s)
90      {
91          return headers.containsKey(s);
92      }
93  
94      @Override
95      public String getHeader(final String s)
96      {
97          final List<Serializable> serializables = headers.get(s);
98          if (serializables.isEmpty())
99          {
100             return null;
101         }
102         return serializables.iterator().next().toString();
103     }
104 
105     @Override
106     public Collection<String> getHeaderNames()
107     {
108         return headers.keySet();
109     }
110 
111     @Override
112     public Collection<String> getHeaders(final String s)
113     {
114         final List<Serializable> serializables = headers.get(s);
115         final Collection<String> strings = new ArrayList<>(serializables.size());
116         for (final Serializable ser : serializables)
117         {
118             strings.add(ser.toString());
119         }
120         return strings;
121     }
122 
123     @Override
124     public int getStatus()
125     {
126         return status;
127     }
128 
129     @Override
130     public void sendError(final int i) throws IOException
131     {
132         status = i;
133         super.sendError(i);
134     }
135 
136     @Override
137     public void sendError(final int i, final String s) throws IOException
138     {
139         status = i;
140         super.sendError(i, s);
141     }
142 
143     @Override
144     public void sendRedirect(final String s) throws IOException
145     {
146         status = SC_MOVED_TEMPORARILY;
147         super.sendRedirect(s);
148     }
149 
150     @Override
151     public void setDateHeader(final String s, final long l)
152     {
153         super.setDateHeader(s, l);
154         final List<Serializable> serializables = ensureHeaderExists(s);
155         serializables.clear();
156         serializables.add(l);
157     }
158 
159     @Override
160     public void setHeader(final String s, final String s2)
161     {
162         super.setHeader(s, s2);
163         final List<Serializable> serializables = ensureHeaderExists(s);
164         serializables.clear();
165         serializables.add(s2);
166     }
167 
168     @Override
169     public void setIntHeader(final String s, final int i)
170     {
171         super.setIntHeader(s, i);
172         final List<Serializable> serializables = ensureHeaderExists(s);
173         serializables.clear();
174         serializables.add(i);
175     }
176 
177     @Override
178     public void setStatus(final int i)
179     {
180         status = i;
181         super.setStatus(i);
182     }
183 
184     @Override
185     public void setStatus(final int i, final String s)
186     {
187         status = i;
188         super.setStatus(i, s);
189     }
190 
191     @Override
192     public String getContentType()
193     {
194         return contentType;
195     }
196 
197     @Override
198     public ServletOutputStream getOutputStream() throws IOException
199     {
200         return new ServletOutputStream()
201         {
202             @Override
203             public void write(final int b) throws IOException
204             {
205                 buffer.write(b);
206             }
207         };
208     }
209 
210     @Override
211     public PrintWriter getWriter() throws IOException
212     {
213         if (writer == null) {
214             writer = new PrintWriter(new OutputStreamWriter(buffer, getCharacterEncoding()), true);
215         }
216         return writer;
217     }
218 
219     @Override
220     public void reset()
221     {
222         super.reset();
223         status = SC_OK;
224         headers.clear();
225         cookies.clear();
226         contentType = null;
227         contentLength = 0;
228     }
229 
230     @Override
231     public void setContentLength(final int i)
232     {
233         super.setContentLength(i);
234         contentLength = i;
235     }
236 
237     @Override
238     public void setContentType(final String s)
239     {
240         contentType = s;
241         super.setContentType(s);
242     }
243 
244     @Override
245     public void flushBuffer() throws IOException
246     {
247         if (writer != null)
248         {
249             writer.flush();
250         }
251         else
252         {
253             buffer.flush();
254         }
255     }
256 
257     public int getContentLength()
258     {
259         return contentLength;
260     }
261 
262     public Collection<Cookie> getCookies()
263     {
264         return cookies;
265     }
266 
267     public Map<String, List<Serializable>> getHeaders()
268     {
269         return headers;
270     }
271 }