001: /*
002: * $Id: MockHttpServletResponse.java 459336 2006-02-15 13:06:22Z jdonnerstag $
003: * $Revision: 459336 $ $Date: 2006-02-15 14:06:22 +0100 (Wed, 15 Feb 2006) $
004: *
005: * ==============================================================================
006: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007: * use this file except in compliance with the License. You may obtain a copy of
008: * 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, software
013: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015: * License for the specific language governing permissions and limitations under
016: * the License.
017: */
018: package wicket.protocol.http;
019:
020: import java.io.ByteArrayOutputStream;
021: import java.io.IOException;
022: import java.io.PrintWriter;
023: import java.io.StringWriter;
024: import java.text.DateFormat;
025: import java.util.ArrayList;
026: import java.util.Collection;
027: import java.util.Date;
028: import java.util.List;
029: import java.util.Locale;
030: import java.util.Set;
031:
032: import javax.servlet.ServletOutputStream;
033: import javax.servlet.http.Cookie;
034: import javax.servlet.http.HttpServletResponse;
035:
036: import wicket.util.value.ValueMap;
037:
038: /**
039: * Mock servlet response. Implements all of the methods from the standard
040: * HttpServletResponse class plus helper methods to aid viewing the generated
041: * response.
042: *
043: * @author Chris Turner
044: */
045: public class MockHttpServletResponse implements HttpServletResponse {
046: private static final int MODE_BINARY = 1;
047:
048: private static final int MODE_NONE = 0;
049:
050: private static final int MODE_TEXT = 2;
051:
052: private ByteArrayOutputStream byteStream;
053:
054: private String characterEncoding = "UTF-8";
055:
056: private int code = HttpServletResponse.SC_OK;
057:
058: private final List cookies = new ArrayList();
059:
060: private String errorMessage = null;
061:
062: private final ValueMap headers = new ValueMap();
063:
064: private Locale locale = null;
065:
066: private int mode = MODE_NONE;
067:
068: private PrintWriter printWriter;
069:
070: private String redirectLocation = null;
071:
072: private ServletOutputStream servletStream;
073:
074: private int status = HttpServletResponse.SC_OK;
075:
076: private StringWriter stringWriter;
077:
078: /**
079: * Create the response object.
080: */
081: public MockHttpServletResponse() {
082: initialize();
083: }
084:
085: /**
086: * Add a cookie to the response.
087: *
088: * @param cookie
089: * The cookie to add
090: */
091: public void addCookie(final Cookie cookie) {
092: cookies.add(cookie);
093: }
094:
095: /**
096: * Add a date header.
097: *
098: * @param name
099: * The header value
100: * @param l
101: * The long value
102: */
103: public void addDateHeader(String name, long l) {
104: DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
105: addHeader(name, df.format(new Date(l)));
106: }
107:
108: /**
109: * Add the given header value, including an additional entry if one already
110: * exists.
111: *
112: * @param name
113: * The name for the header
114: * @param value
115: * The value for the header
116: */
117: public void addHeader(final String name, final String value) {
118: List list = (List) headers.get(name);
119: if (list == null) {
120: list = new ArrayList(1);
121: headers.put(name, list);
122: }
123: list.add(value);
124: }
125:
126: /**
127: * Add an int header value.
128: *
129: * @param name
130: * The header name
131: * @param i
132: * The value
133: */
134: public void addIntHeader(final String name, final int i) {
135: addHeader(name, "" + i);
136: }
137:
138: /**
139: * Check if the response contains the given header name.
140: *
141: * @param name
142: * The name to check
143: * @return Whether header in response or not
144: */
145: public boolean containsHeader(final String name) {
146: return headers.containsKey(name);
147: }
148:
149: /**
150: * Encode the redirectLocation URL. Does no changes as this test
151: * implementation uses cookie based url tracking.
152: *
153: * @param url
154: * The url to encode
155: * @return The encoded url
156: */
157: public String encodeRedirectUrl(final String url) {
158: return url;
159: }
160:
161: /**
162: * Encode the redirectLocation URL. Does no changes as this test
163: * implementation uses cookie based url tracking.
164: *
165: * @param url
166: * The url to encode
167: * @return The encoded url
168: */
169: public String encodeRedirectURL(final String url) {
170: return url;
171: }
172:
173: /**
174: * Encode thr URL. Does no changes as this test implementation uses cookie
175: * based url tracking.
176: *
177: * @param url
178: * The url to encode
179: * @return The encoded url
180: */
181: public String encodeUrl(final String url) {
182: return url;
183: }
184:
185: /**
186: * Encode thr URL. Does no changes as this test implementation uses cookie
187: * based url tracking.
188: *
189: * @param url
190: * The url to encode
191: * @return The encoded url
192: */
193: public String encodeURL(final String url) {
194: return url;
195: }
196:
197: /**
198: * Flush the buffer.
199: *
200: * @throws IOException
201: */
202: public void flushBuffer() throws IOException {
203: }
204:
205: /**
206: * Get the binary content that was written to the servlet stream.
207: *
208: * @return The binary content
209: */
210: public byte[] getBinaryContent() {
211: return byteStream.toByteArray();
212: }
213:
214: /**
215: * Return the current buffer size
216: *
217: * @return The buffer size
218: */
219: public int getBufferSize() {
220: if (mode == MODE_NONE) {
221: return 0;
222: } else if (mode == MODE_BINARY) {
223: return byteStream.size();
224: } else {
225: return stringWriter.getBuffer().length();
226: }
227: }
228:
229: /**
230: * Get the character encoding of the response.
231: *
232: * @return The character encoding
233: */
234: public String getCharacterEncoding() {
235: return characterEncoding;
236: }
237:
238: /**
239: * Get the response code for this request.
240: *
241: * @return The response code
242: */
243: public int getCode() {
244: return code;
245: }
246:
247: /**
248: * Get all of the cookies that have been added to the response.
249: *
250: * @return The collection of cookies
251: */
252: public Collection getCookies() {
253: return cookies;
254: }
255:
256: /**
257: * Get the text document that was written as part of this response.
258: *
259: * @return The document
260: */
261: public String getDocument() {
262: if (mode == MODE_BINARY) {
263: return new String(byteStream.toByteArray());
264: } else {
265: return stringWriter.getBuffer().toString();
266: }
267: }
268:
269: /**
270: * Get the error message.
271: *
272: * @return The error message, or null if no message
273: */
274: public String getErrorMessage() {
275: return errorMessage;
276: }
277:
278: /**
279: * Return the value of the given named header.
280: *
281: * @param name
282: * The header name
283: * @return The value, or null
284: */
285: public String getHeader(final String name) {
286: List l = (List) headers.get(name);
287: if (l == null || l.size() < 1) {
288: return null;
289: } else {
290: return (String) l.get(0);
291: }
292: }
293:
294: /**
295: * Get the names of all of the headers.
296: *
297: * @return The header names
298: */
299: public Set getHeaderNames() {
300: return headers.keySet();
301: }
302:
303: /**
304: * Get the encoded locale
305: *
306: * @return The locale
307: */
308: public Locale getLocale() {
309: return locale;
310: }
311:
312: /**
313: * Get the output stream for writing binary data from the servlet.
314: *
315: * @return The binary output stream.
316: * @throws IOException
317: * If stream not available
318: */
319: public ServletOutputStream getOutputStream() throws IOException {
320: if (mode == MODE_TEXT) {
321: throw new IllegalArgumentException(
322: "Can't write binary after already selecting text");
323: }
324: mode = MODE_BINARY;
325: return servletStream;
326: }
327:
328: /**
329: * Get the location that was redirected to.
330: *
331: * @return The redirect location, or null if not a redirect
332: */
333: public String getRedirectLocation() {
334: return redirectLocation;
335: }
336:
337: /**
338: * Get the status code.
339: *
340: * @return The status code
341: */
342: public int getStatus() {
343: return status;
344: }
345:
346: /**
347: * Get the print writer for writing text output for this response.
348: *
349: * @return The writer
350: * @throws IOException
351: * Not used
352: */
353: public PrintWriter getWriter() throws IOException {
354: if (mode == MODE_BINARY) {
355: throw new IllegalArgumentException(
356: "Can't write text after already selecting binary");
357: }
358: mode = MODE_TEXT;
359: return printWriter;
360: }
361:
362: /**
363: * Reset the response ready for reuse.
364: */
365: public void initialize() {
366: cookies.clear();
367: headers.clear();
368: code = HttpServletResponse.SC_OK;
369: errorMessage = null;
370: redirectLocation = null;
371: status = HttpServletResponse.SC_OK;
372: characterEncoding = "UTF-8";
373: locale = null;
374:
375: byteStream = new ByteArrayOutputStream();
376: servletStream = new ServletOutputStream() {
377: public void write(int b) {
378: byteStream.write(b);
379: }
380: };
381: stringWriter = new StringWriter();
382: printWriter = new PrintWriter(stringWriter) {
383: public void close() {
384: // Do nothing
385: }
386:
387: public void flush() {
388: // Do nothing
389: }
390: };
391: mode = MODE_NONE;
392: }
393:
394: /**
395: * Always returns false.
396: *
397: * @return Always false
398: */
399: public boolean isCommitted() {
400: return false;
401: }
402:
403: /**
404: * Return whether the servlet returned an error code or not.
405: *
406: * @return Whether an error occurred or not
407: */
408: public boolean isError() {
409: return (code != HttpServletResponse.SC_OK);
410: }
411:
412: /**
413: * Check whether the response was redirected or not.
414: *
415: * @return Whether the state was redirected or not
416: */
417: public boolean isRedirect() {
418: return (redirectLocation != null);
419: }
420:
421: /**
422: * Delegate to initialise method.
423: */
424: public void reset() {
425: initialize();
426: }
427:
428: /**
429: * Clears the buffer.
430: */
431: public void resetBuffer() {
432: if (mode == MODE_BINARY) {
433: byteStream.reset();
434: } else if (mode == MODE_TEXT) {
435: stringWriter.getBuffer().delete(0,
436: stringWriter.getBuffer().length());
437: }
438: }
439:
440: /**
441: * Send an error code. This implementation just sets the internal error
442: * state information.
443: *
444: * @param code
445: * The code
446: * @throws IOException
447: * Not used
448: */
449: public void sendError(final int code) throws IOException {
450: this .code = code;
451: errorMessage = null;
452: }
453:
454: /**
455: * Send an error code. This implementation just sets the internal error
456: * state information.
457: *
458: * @param code
459: * The error code
460: * @param msg
461: * The error message
462: * @throws IOException
463: * Not used
464: */
465: public void sendError(final int code, final String msg)
466: throws IOException {
467: this .code = code;
468: errorMessage = msg;
469: }
470:
471: /**
472: * Indicate sending of a redirectLocation to a particular named resource.
473: * This implementation just keeps hold of the redirectLocation info and
474: * makes it available for query.
475: *
476: * @param location
477: * The location to redirectLocation to
478: * @throws IOException
479: * Not used
480: */
481: public void sendRedirect(String location) throws IOException {
482: this .redirectLocation = location;
483: }
484:
485: /**
486: * Method ignored.
487: *
488: * @param size
489: * The size
490: */
491: public void setBufferSize(final int size) {
492: }
493:
494: /**
495: * Set the character encoding.
496: *
497: * @param characterEncoding
498: * The character encoding
499: */
500: public void setCharacterEncoding(final String characterEncoding) {
501: this .characterEncoding = characterEncoding;
502: }
503:
504: /**
505: * Set the content length.
506: *
507: * @param length
508: * The length
509: */
510: public void setContentLength(final int length) {
511: setIntHeader("Content-Length", length);
512: }
513:
514: /**
515: * Set the content type.
516: *
517: * @param type
518: * The content type
519: */
520: public void setContentType(final String type) {
521: setHeader("Content-Type", type);
522: }
523:
524: /**
525: * Set a date header.
526: *
527: * @param name
528: * The header name
529: * @param l
530: * The long value
531: */
532: public void setDateHeader(final String name, final long l) {
533: DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
534: setHeader(name, df.format(new Date(l)));
535: }
536:
537: /**
538: * Set the given header value.
539: *
540: * @param name
541: * The name for the header
542: * @param value
543: * The value for the header
544: */
545: public void setHeader(final String name, final String value) {
546: List l = new ArrayList(1);
547: l.add(value);
548: headers.put(name, l);
549: }
550:
551: /**
552: * Set an int header value.
553: *
554: * @param name
555: * The header name
556: * @param i
557: * The value
558: */
559: public void setIntHeader(final String name, final int i) {
560: setHeader(name, "" + i);
561: }
562:
563: /**
564: * Set the locale in the response header.
565: *
566: * @param locale
567: * The locale
568: */
569: public void setLocale(final Locale locale) {
570: this .locale = locale;
571: }
572:
573: /**
574: * Set the status for this response.
575: *
576: * @param status
577: * The status
578: */
579: public void setStatus(final int status) {
580: this .status = status;
581: }
582:
583: /**
584: * Set the status for this response.
585: *
586: * @param status
587: * The status
588: * @param msg
589: * The message
590: * @deprecated
591: */
592: public void setStatus(final int status, final String msg) {
593: setStatus(status);
594: }
595: }
|