/* * Copyright 2004-2010 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.slim3.tester; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import javax.servlet.ServletOutputStream; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; /** * A mock implementation for {@link MockHttpServletResponse}. * * @author higa * @since 1.0.0 * */ public class MockHttpServletResponse implements HttpServletResponse { /** * The list for {@link Cookie}. */ protected List<Cookie> cookieList = new ArrayList<Cookie>(); /** * The map for the response header. */ protected Map<String, List<String>> headerMap = new HashMap<String, List<String>>(); /** * The committed flag. */ protected boolean committed = false; /** * The status. */ protected int status = SC_OK; /** * The message. */ protected String message; /** * The locale. */ protected Locale locale; /** * The character encoding. */ protected String characterEncoding = "UTF-8"; /** * The source output. */ protected ByteArrayOutputStream sourceOutput = new ByteArrayOutputStream(); /** * The writer. */ protected PrintWriter writer; /** * The output stream. */ protected ServletOutputStream outputStream; /** * Whether getWriter method is called. */ protected boolean getWriterCalled; /** * Whether getOutputStream method is called. */ protected boolean getOutputStreamCalled; /** * The buffer size. */ protected int bufferSize = 32; /** * The redirect path */ protected String redirectPath; /** * Constructor. */ public MockHttpServletResponse() { } /** * Returns the cookies. * * @return the cookies */ public Cookie[] getCookies() { return cookieList.toArray(new Cookie[cookieList.size()]); } public void addCookie(Cookie cookie) { cookieList.add(cookie); } public boolean containsHeader(String name) { return headerMap.containsKey(name); } public String encodeURL(String url) { return url; } public String encodeRedirectURL(String url) { return url; } @SuppressWarnings("deprecation") public String encodeUrl(String url) { return encodeURL(url); } @SuppressWarnings("deprecation") public String encodeRedirectUrl(String url) { return encodeRedirectUrl(url); } /** * Returns the status. * * @return the status */ public int getStatus() { return status; } @SuppressWarnings("deprecation") public void setStatus(int status, String message) { assertNotCommitted(); this.status = status; this.message = message; resetBuffer(); } public void setStatus(int status) { setStatus(status, getResponseStatusMessage(status)); } /** * Returns the response status message. * * @param status * the status * @return the response status message */ protected String getResponseStatusMessage(int status) { switch (status) { case HttpServletResponse.SC_OK: return "OK"; case HttpServletResponse.SC_ACCEPTED: return "Accepted"; case HttpServletResponse.SC_BAD_GATEWAY: return "Bad Gateway"; case HttpServletResponse.SC_BAD_REQUEST: return "Bad Request"; case HttpServletResponse.SC_CONFLICT: return "Conflict"; case HttpServletResponse.SC_CONTINUE: return "Continue"; case HttpServletResponse.SC_CREATED: return "Created"; case HttpServletResponse.SC_EXPECTATION_FAILED: return "Expectation Failed"; case HttpServletResponse.SC_FORBIDDEN: return "Forbidden"; case HttpServletResponse.SC_GATEWAY_TIMEOUT: return "Gateway Timeout"; case HttpServletResponse.SC_GONE: return "Gone"; case HttpServletResponse.SC_HTTP_VERSION_NOT_SUPPORTED: return "HTTP Version Not Supported"; case HttpServletResponse.SC_INTERNAL_SERVER_ERROR: return "Internal Server Error"; case HttpServletResponse.SC_LENGTH_REQUIRED: return "Length Required"; case HttpServletResponse.SC_METHOD_NOT_ALLOWED: return "Method Not Allowed"; case HttpServletResponse.SC_MOVED_PERMANENTLY: return "Moved Permanently"; case HttpServletResponse.SC_MOVED_TEMPORARILY: return "Moved Temporarily"; case HttpServletResponse.SC_MULTIPLE_CHOICES: return "Multiple Choices"; case HttpServletResponse.SC_NO_CONTENT: return "No Content"; case HttpServletResponse.SC_NON_AUTHORITATIVE_INFORMATION: return "Non-Authoritative Information"; case HttpServletResponse.SC_NOT_ACCEPTABLE: return "Not Acceptable"; case HttpServletResponse.SC_NOT_FOUND: return "Not Found"; case HttpServletResponse.SC_NOT_IMPLEMENTED: return "Not Implemented"; case HttpServletResponse.SC_NOT_MODIFIED: return "Not Modified"; case HttpServletResponse.SC_PARTIAL_CONTENT: return "Partial Content"; case HttpServletResponse.SC_PAYMENT_REQUIRED: return "Payment Required"; case HttpServletResponse.SC_PRECONDITION_FAILED: return "Precondition Failed"; case HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED: return "Proxy Authentication Required"; case HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE: return "Request Entity Too Large"; case HttpServletResponse.SC_REQUEST_TIMEOUT: return "Request Timeout"; case HttpServletResponse.SC_REQUEST_URI_TOO_LONG: return "Request URI Too Long"; case HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE: return "Requested Range Not Satisfiable"; case HttpServletResponse.SC_RESET_CONTENT: return "Reset Content"; case HttpServletResponse.SC_SEE_OTHER: return "See Other"; case HttpServletResponse.SC_SERVICE_UNAVAILABLE: return "Service Unavailable"; case HttpServletResponse.SC_SWITCHING_PROTOCOLS: return "Switching Protocols"; case HttpServletResponse.SC_UNAUTHORIZED: return "Unauthorized"; case HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE: return "Unsupported Media Type"; case HttpServletResponse.SC_USE_PROXY: return "Use Proxy"; case 207: return "Multi-Status"; case 422: return "Unprocessable Entity"; case 423: return "Locked"; case 507: return "Insufficient Storage"; default: return "HTTP Response Status " + status; } } /** * Asserts this response is not committed. */ protected void assertNotCommitted() { if (isCommitted()) { throw new IllegalStateException("Already committed"); } } /** * Returns the message. * * @return the message */ public String getMessage() { return message; } public void sendError(int status, String message) throws IOException { setStatus(status, message); } public void sendError(int status) throws IOException { setStatus(status); } public void sendRedirect(String path) throws IOException { setStatus(SC_MOVED_TEMPORARILY); redirectPath = path; } /** * Returns the redirect path. * * @return the redirect path */ public String getRedirectPath() { return redirectPath; } /** * Returns the header as {@link Enumeration}. * * @param name * the name * @return the header */ public Enumeration<String> getHeaders(String name) { List<String> values = getHeaderList(name); if (values == null) { values = Collections.emptyList(); } return Collections.enumeration(values); } /** * Returns the header as string. * * @param name * the name * @return the header */ public String getHeader(String name) { List<String> values = getHeaderList(name); if (values != null) { return values.get(0); } return null; } /** * Returns the header as date. * * @param name * the name * @return the header */ public long getDateHeader(String name) { String value = getHeader(name); return HeaderUtil.convertStringToDate(value); } /** * Returns the header as int. * * @param name * the name * @return the header */ public int getIntHeader(String name) { String value = getHeader(name); return HeaderUtil.convertStringToInt(value); } /** * Returns the header as list. * * @param name * the name * @return the header */ protected List<String> getHeaderList(String name) { return headerMap.get(name.toLowerCase()); } /** * Returns the header names. * * @return the header names */ public Enumeration<String> getHeaderNames() { return Collections.enumeration(headerMap.keySet()); } public void setHeader(String name, String value) { List<String> values = new ArrayList<String>(); values.add(value); headerMap.put(name.toLowerCase(), values); } public void addHeader(String name, String value) { List<String> values = getHeaderList(name); if (values == null) { values = new ArrayList<String>(); } values.add(value); headerMap.put(name.toLowerCase(), values); } public void setDateHeader(String name, long value) { setHeader(name, HeaderUtil.convertDateToString(value)); } public void addDateHeader(String name, long value) { addHeader(name, HeaderUtil.convertDateToString(value)); } public void setIntHeader(String name, int value) { setHeader(name, HeaderUtil.convertIntToString(value)); } public void addIntHeader(String name, int value) { addHeader(name, HeaderUtil.convertIntToString(value)); } /** * Returns the content length. * * @return the content length */ public int getContentLength() { return getIntHeader("content-length"); } public void setContentLength(int contentLength) { setIntHeader("content-length", contentLength); } public String getContentType() { return getHeader("content-type"); } public void setContentType(String contentType) { setHeader("content-type", contentType); } public String getCharacterEncoding() { return characterEncoding; } public void setCharacterEncoding(String characterEncoding) { this.characterEncoding = characterEncoding; } public ServletOutputStream getOutputStream() throws IOException { if (getWriterCalled) { throw new IllegalStateException( "The getWriter method is already called."); } if (!getOutputStreamCalled) { getOutputStreamCalled = true; outputStream = new MockServletOutputStream(sourceOutput); } return outputStream; } public PrintWriter getWriter() throws IOException { if (getOutputStreamCalled) { throw new IllegalStateException( "The getOutputStream method is already called."); } if (!getWriterCalled) { getWriterCalled = true; writer = new PrintWriter(new OutputStreamWriter( sourceOutput, characterEncoding)); } return writer; } /** * Returns the output as array of bytes. * * @return the output * @throws IOException * if {@link IOException} is encountered */ public byte[] getOutputAsByteArray() throws IOException { return sourceOutput.toByteArray(); } /** * Returns the output as string. * * @return the output * @throws IOException * if {@link IOException} is encountered */ public String getOutputAsString() throws IOException { return new String(getOutputAsByteArray(), characterEncoding); } public int getBufferSize() { return bufferSize; } public void setBufferSize(int bufferSize) { if (getOutputStreamCalled) { throw new IllegalStateException( "The getOutputStream method is already called."); } if (getWriterCalled) { throw new IllegalStateException( "The getWriter method is already called."); } this.bufferSize = bufferSize; sourceOutput = new ByteArrayOutputStream(bufferSize); } public void flushBuffer() throws IOException { if (outputStream != null) { outputStream.flush(); } else if (writer != null) { writer.flush(); } } public void resetBuffer() { } public boolean isCommitted() { return committed; } public void reset() { committed = false; } public void setLocale(Locale locale) { this.locale = locale; } public Locale getLocale() { return locale; } }