1   /*
2    * Copyright 2002-2004 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.huihoo.jfox.soaf.util.filter;
18  
19  import java.io.ByteArrayOutputStream;
20  import java.io.IOException;
21  import java.io.OutputStreamWriter;
22  import java.io.PrintWriter;
23  import java.io.UnsupportedEncodingException;
24  import java.io.Writer;
25  import java.util.ArrayList;
26  import java.util.Collections;
27  import java.util.HashMap;
28  import java.util.Iterator;
29  import java.util.LinkedList;
30  import java.util.List;
31  import java.util.Locale;
32  import java.util.Map;
33  import java.util.Set;
34  
35  import javax.servlet.ServletOutputStream;
36  import javax.servlet.http.Cookie;
37  import javax.servlet.http.HttpServletResponse;
38  
39  /***
40   * Mock implementation of the HttpServletResponse interface.
41   *
42   * <p>Used for testing the web framework; also useful
43   * for testing application controllers.
44   *
45   * @author Rod Johnson
46   * @author Juergen Hoeller
47   * @since 1.0.2
48   */
49  public class MockHttpServletResponse implements HttpServletResponse {
50  
51  	public static final int DEFAULT_SERVER_PORT = 80;
52  
53  
54  	//---------------------------------------------------------------------
55  	// ServletResponse properties
56  	//---------------------------------------------------------------------
57  
58  	private String characterEncoding = "utf-8";
59  
60  	private final ByteArrayOutputStream content = new ByteArrayOutputStream();
61  
62  	private final MockServletOutputStream outputStream = new MockServletOutputStream(this.content);
63  
64  	private PrintWriter writer;
65  
66  	private int contentLength = 0;
67  
68  	private String contentType;
69  
70  	private int bufferSize = 4096;
71  
72  	private boolean committed;
73  
74  	private Locale locale = Locale.getDefault();
75  
76  
77  	//---------------------------------------------------------------------
78  	// HttpServletResponse properties
79  	//---------------------------------------------------------------------
80  
81  	private final List cookies = new ArrayList();
82  
83  	private final Map headers = new HashMap();
84  
85  	private int status = HttpServletResponse.SC_OK;
86  
87  	private String errorMessage;
88  
89  	private String redirectedUrl;
90  
91  	private String forwardedUrl;
92  
93  	private String includedUrl;
94  
95  
96  	//---------------------------------------------------------------------
97  	// ServletResponse interface
98  	//---------------------------------------------------------------------
99  
100 	public void setCharacterEncoding(String characterEncoding) {
101 		this.characterEncoding = characterEncoding;
102 	}
103 
104 	public String getCharacterEncoding() {
105 		return characterEncoding;
106 	}
107 
108 	public ServletOutputStream getOutputStream() {
109 		return this.outputStream;
110 	}
111 
112 	public PrintWriter getWriter() throws UnsupportedEncodingException {
113 		if (this.writer == null) {
114 			Writer targetWriter = (this.characterEncoding != null ?
115 					new OutputStreamWriter(this.content, this.characterEncoding) : new OutputStreamWriter(this.content));
116 			this.writer = new PrintWriter(targetWriter);
117 		}
118 		return writer;
119 	}
120 
121 	public byte[] getContentAsByteArray() {
122 		flushBuffer();
123 		return this.content.toByteArray();
124 	}
125 
126 	public String getContentAsString() throws UnsupportedEncodingException {
127 		flushBuffer();
128 		return (this.characterEncoding != null) ?
129 				this.content.toString(this.characterEncoding) : this.content.toString();
130 	}
131 
132 	public void setContentLength(int contentLength) {
133 		this.contentLength = contentLength;
134 	}
135 
136 	public int getContentLength() {
137 		return contentLength;
138 	}
139 
140 	public void setContentType(String contentType) {
141 		this.contentType = contentType;
142 	}
143 
144 	public String getContentType() {
145 		return contentType;
146 	}
147 
148 	public void setBufferSize(int bufferSize) {
149 		this.bufferSize = bufferSize;
150 	}
151 
152 	public int getBufferSize() {
153 		return bufferSize;
154 	}
155 
156 	public void flushBuffer() {
157 		if (this.writer != null) {
158 			this.writer.flush();
159 		}
160 		if (this.outputStream != null) {
161 			try {
162 				this.outputStream.flush();
163 			}
164 			catch (IOException ex) {
165 				throw new IllegalStateException("Could not flush OutputStream: " + ex.getMessage());
166 			}
167 		}
168 		this.committed = true;
169 	}
170 
171 	public void resetBuffer() {
172 		if (this.committed) {
173 			throw new IllegalStateException("Cannot reset buffer - response is already committed");
174 		}
175 		this.content.reset();
176 	}
177 
178 	public void setCommitted(boolean committed) {
179 		this.committed = committed;
180 	}
181 
182 	public boolean isCommitted() {
183 		return committed;
184 	}
185 
186 	public void reset() {
187 		resetBuffer();
188 		this.characterEncoding = null;
189 		this.contentLength = 0;
190 		this.contentType = null;
191 		this.locale = null;
192 		this.cookies.clear();
193 		this.headers.clear();
194 		this.status = HttpServletResponse.SC_OK;
195 		this.errorMessage = null;
196 	}
197 
198 	public void setLocale(Locale locale) {
199 		this.locale = locale;
200 	}
201 
202 	public Locale getLocale() {
203 		return locale;
204 	}
205 
206 
207 	//---------------------------------------------------------------------
208 	// HttpServletResponse interface
209 	//---------------------------------------------------------------------
210 
211 	public void addCookie(Cookie cookie) {
212 		this.cookies.add(cookie);
213 	}
214 
215 	public Cookie[] getCookies() {
216 		return (Cookie[]) this.cookies.toArray(new Cookie[this.cookies.size()]);
217 	}
218 
219 	public Cookie getCookie(String name) {
220 		for (Iterator it = this.cookies.iterator(); it.hasNext();) {
221 			Cookie cookie = (Cookie) it.next();
222 			if (name.equals(cookie.getName())) {
223 				return cookie;
224 			}
225 		}
226 		return null;
227 	}
228 
229 	public boolean containsHeader(String name) {
230 		return this.headers.containsKey(name);
231 	}
232 
233 	public Object getHeader(String name) {
234 		return this.headers.get(name);
235 	}
236 
237 	public List getHeaders(String name) {
238 		Object value = this.headers.get(name);
239 		if (value instanceof List) {
240 			return (List) value;
241 		}
242 		else if (value != null) {
243 			return Collections.singletonList(value);
244 		}
245 		else {
246 			return Collections.EMPTY_LIST;
247 		}
248 	}
249 
250 	public Set getHeaderNames() {
251 		return this.headers.keySet();
252 	}
253 
254 	public String encodeURL(String url) {
255 		return url;
256 	}
257 
258 	public String encodeRedirectURL(String url) {
259 		return url;
260 	}
261 
262 	public String encodeUrl(String url) {
263 		return url;
264 	}
265 
266 	public String encodeRedirectUrl(String url) {
267 		return url;
268 	}
269 
270 	public void sendError(int status, String errorMessage) throws IOException {
271 		if (this.committed) {
272 			throw new IllegalStateException("Cannot set error status - response is already committed");
273 		}
274 		this.status = status;
275 		this.errorMessage = errorMessage;
276 		this.committed = true;
277 	}
278 
279 	public void sendError(int status) throws IOException {
280 		if (this.committed) {
281 			throw new IllegalStateException("Cannot set error status - response is already committed");
282 		}
283 		this.status = status;
284 		this.committed = true;
285 	}
286 
287 	public void sendRedirect(String url) throws IOException {
288 		if (this.committed) {
289 			throw new IllegalStateException("Cannot send redirect - response is already committed");
290 		}
291 		this.redirectedUrl = url;
292 		this.committed = true;
293 	}
294 
295 	public String getRedirectedUrl() {
296 		return redirectedUrl;
297 	}
298 
299 	public void setDateHeader(String name, long value) {
300 		this.headers.put(name, new Long(value));
301 	}
302 
303 	public void addDateHeader(String name, long value) {
304 		doAddHeader(name, new Long(value));
305 	}
306 
307 	public void setHeader(String name, String value) {
308 		this.headers.put(name, value);
309 	}
310 
311 	public void addHeader(String name, String value) {
312 		doAddHeader(name, value);
313 	}
314 
315 	public void setIntHeader(String name, int value) {
316 		this.headers.put(name, new Integer(value));
317 	}
318 
319 	public void addIntHeader(String name, int value) {
320 		doAddHeader(name, new Integer(value));
321 	}
322 
323 	private void doAddHeader(String name, Object value) {
324 		Object oldValue = this.headers.get(name);
325 		if (oldValue instanceof List) {
326 			List list = (List) oldValue;
327 			list.add(value);
328 		}
329 		else if (oldValue != null) {
330 			List list = new LinkedList();
331 			list.add(oldValue);
332 			list.add(value);
333 			this.headers.put(name, list);
334 		}
335 		else {
336 			this.headers.put(name, value);
337 		}
338 	}
339 
340 	public void setStatus(int status) {
341 		this.status = status;
342 	}
343 
344 	public void setStatus(int status, String errorMessage) {
345 		this.status = status;
346 		this.errorMessage = errorMessage;
347 	}
348 
349 	public int getStatus() {
350 		return status;
351 	}
352 
353 	public String getErrorMessage() {
354 		return errorMessage;
355 	}
356 
357 
358 	//---------------------------------------------------------------------
359 	// Methods for MockRequestDispatcher
360 	//---------------------------------------------------------------------
361 
362 	public void setForwardedUrl(String forwardedUrl) {
363 		this.forwardedUrl = forwardedUrl;
364 	}
365 
366 	public String getForwardedUrl() {
367 		return forwardedUrl;
368 	}
369 
370 	public void setIncludedUrl(String includedUrl) {
371 		this.includedUrl = includedUrl;
372 	}
373 
374 	public String getIncludedUrl() {
375 		return includedUrl;
376 	}
377 
378 }