001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.jcs3.jcache.extras.web; 020 021import java.io.IOException; 022import java.io.OutputStream; 023import java.io.OutputStreamWriter; 024import java.io.PrintWriter; 025import java.io.Serializable; 026import java.util.ArrayList; 027import java.util.Collection; 028import java.util.LinkedList; 029import java.util.List; 030import java.util.Map; 031import java.util.TreeMap; 032import java.util.concurrent.CopyOnWriteArraySet; 033import javax.servlet.ServletOutputStream; 034import javax.servlet.http.Cookie; 035import javax.servlet.http.HttpServletResponse; 036import javax.servlet.http.HttpServletResponseWrapper; 037 038public class InMemoryResponse extends HttpServletResponseWrapper implements Serializable 039{ 040 private final OutputStream buffer; 041 042 private final Collection<Cookie> cookies = new CopyOnWriteArraySet<>(); 043 private final Map<String, List<Serializable>> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); 044 private int status = SC_OK; 045 private String contentType; 046 private PrintWriter writer; 047 private int contentLength; 048 049 public InMemoryResponse(final HttpServletResponse response, final OutputStream baos) 050 { 051 super(response); 052 this.buffer = baos; 053 } 054 055 private List<Serializable> ensureHeaderExists(final String s) 056 { 057 return headers.computeIfAbsent(s, k -> new LinkedList<>()); 058 } 059 060 @Override 061 public void addCookie(final Cookie cookie) 062 { 063 super.addCookie(cookie); 064 cookies.add(cookie); 065 } 066 067 @Override 068 public void addDateHeader(final String s, final long l) 069 { 070 super.addDateHeader(s, l); 071 ensureHeaderExists(s).add(l); 072 } 073 074 @Override 075 public void addHeader(final String s, final String s2) 076 { 077 super.addHeader(s, s2); 078 ensureHeaderExists(s).add(s2); 079 } 080 081 @Override 082 public void addIntHeader(final String s, final int i) 083 { 084 super.addIntHeader(s, i); 085 ensureHeaderExists(s).add(i); 086 } 087 088 @Override 089 public boolean containsHeader(final String s) 090 { 091 return headers.containsKey(s); 092 } 093 094 @Override 095 public String getHeader(final String s) 096 { 097 final List<Serializable> serializables = headers.get(s); 098 if (serializables.isEmpty()) 099 { 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}