1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.module.cache.filter;
35
36 import org.apache.commons.collections.MultiMap;
37 import org.apache.commons.collections.map.MultiValueMap;
38
39 import javax.servlet.ServletOutputStream;
40 import javax.servlet.http.HttpServletResponse;
41 import javax.servlet.http.HttpServletResponseWrapper;
42 import java.io.IOException;
43 import java.io.OutputStreamWriter;
44 import java.io.PrintWriter;
45 import java.text.SimpleDateFormat;
46 import java.text.ParseException;
47 import java.util.Date;
48 import java.util.Collection;
49 import java.util.Locale;
50
51
52
53
54
55
56 public class CacheResponseWrapper extends HttpServletResponseWrapper {
57 private final ServletOutputStream wrappedStream;
58 private PrintWriter wrappedWriter = null;
59 private final MultiMap headers = new MultiValueMap();
60 private int status = SC_OK;
61 private boolean isError;
62 private String redirectionLocation;
63
64 public CacheResponseWrapper(final HttpServletResponse response, final ServletOutputStream wrappedStream) {
65 super(response);
66 this.wrappedStream = wrappedStream;
67 }
68
69
70 public ServletOutputStream getOutputStream() throws IOException {
71 return wrappedStream;
72 }
73
74 public PrintWriter getWriter() throws IOException {
75 if (wrappedWriter == null) {
76 String encoding = getCharacterEncoding();
77 wrappedWriter = encoding != null
78 ? new PrintWriter(new OutputStreamWriter(getOutputStream(), encoding))
79 : new PrintWriter(new OutputStreamWriter(getOutputStream()));
80 }
81
82 return wrappedWriter;
83 }
84
85 public void flushBuffer() throws IOException {
86 super.flushBuffer();
87 flush();
88 }
89
90 public void flush() throws IOException {
91 wrappedStream.flush();
92
93 if (wrappedWriter != null) {
94 wrappedWriter.flush();
95 }
96 }
97
98
99 public void reset() {
100 super.reset();
101
102
103
104 wrappedWriter = null;
105 status = SC_OK;
106
107
108 headers.clear();
109
110
111 }
112
113
114 public void resetBuffer() {
115 super.resetBuffer();
116
117
118
119 wrappedWriter = null;
120 }
121
122 public int getStatus() {
123 return status;
124 }
125
126 public boolean isError() {
127 return isError;
128 }
129
130 public MultiMap getHeaders() {
131 return headers;
132 }
133
134 public long getLastModified() {
135
136
137 final Collection values = (Collection) headers.get("Last-Modified");
138 if (values == null || values.size() != 1) {
139 throw new IllegalStateException("Can't get Last-Modified header : no or multiple values : " + values);
140 }
141 final Object value = values.iterator().next();
142 if (value instanceof String) {
143 return parseStringDate((String) value);
144 } else if (value instanceof Long) {
145 return ((Long)value).longValue();
146 } else {
147 throw new IllegalStateException("Can't get Last-Modified header : " + value);
148 }
149 }
150
151 private long parseStringDate(String value) {
152 try {
153 final SimpleDateFormat f = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.ENGLISH);
154 final Date date = f.parse(value);
155 return date.getTime();
156 } catch (ParseException e) {
157 throw new IllegalStateException("Could not parse Last-Modified header with value " + value + " : " + e.getMessage());
158 }
159 }
160
161 public String getRedirectionLocation() {
162 return redirectionLocation;
163 }
164
165 public void setDateHeader(String name, long date) {
166 super.setDateHeader(name, date);
167 replaceHeader(name, new Long(date));
168 }
169
170 public void addDateHeader(String name, long date) {
171 super.addDateHeader(name, date);
172 appendHeader(name, new Long(date));
173 }
174
175 public void setHeader(String name, String value) {
176 super.setHeader(name, value);
177 replaceHeader(name, value);
178 }
179
180 public void addHeader(String name, String value) {
181 super.addHeader(name, value);
182 appendHeader(name, value);
183 }
184
185 public void setIntHeader(String name, int value) {
186 super.setIntHeader(name, value);
187 replaceHeader(name, new Integer(value));
188 }
189
190 public void addIntHeader(String name, int value) {
191 super.addIntHeader(name, value);
192 appendHeader(name, new Integer(value));
193 }
194
195 private void replaceHeader(String name, Object value) {
196 headers.remove(name);
197 appendHeader(name, value);
198 }
199
200 private void appendHeader(String name, Object value) {
201 headers.put(name, value);
202 }
203
204 public void setStatus(int status) {
205 super.setStatus(status);
206 this.status = status;
207 }
208
209 public void setStatus(int status, String string) {
210 super.setStatus(status, string);
211 this.status = status;
212 }
213
214 public void sendRedirect(String location) throws IOException {
215 this.status = SC_MOVED_TEMPORARILY;
216 this.redirectionLocation = location;
217 super.sendRedirect(location);
218 }
219
220 public void sendError(int status, String string) throws IOException {
221 super.sendError(status, string);
222 this.status = status;
223 this.isError = true;
224 }
225
226 public void sendError(int status) throws IOException {
227 super.sendError(status);
228 this.status = status;
229 this.isError = true;
230 }
231 }