001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.rest.mock2; 014 015import java.io.*; 016import java.util.*; 017 018import javax.servlet.*; 019import javax.servlet.http.*; 020 021import org.apache.juneau.internal.*; 022import org.apache.juneau.rest.util.*; 023 024/** 025 * An implementation of {@link HttpServletResponse} for mocking purposes. 026 * 027 * <ul class='seealso'> 028 * <li class='link'>{@doc juneau-rest-mock} 029 * </ul> 030*/ 031public class MockServletResponse implements HttpServletResponse { 032 033 private String characterEncoding = "UTF-8"; 034 private ByteArrayOutputStream baos = new ByteArrayOutputStream(); 035 private int bufferSize = 0; 036 private Locale locale; 037 private int sc; 038 private String msg; 039 private Map<String,String[]> headerMap = new LinkedHashMap<>(); 040 041 /** 042 * Creates a new servlet response. 043 * 044 * @return A new response. 045 */ 046 public static MockServletResponse create() { 047 return new MockServletResponse(); 048 } 049 050 /** 051 * Returns the response message. 052 * 053 * @return The response message. 054 */ 055 public String getMessage() { 056 return msg; 057 } 058 059 @Override /* HttpServletResponse */ 060 public String getCharacterEncoding() { 061 return characterEncoding ; 062 } 063 064 @Override /* HttpServletResponse */ 065 public String getContentType() { 066 return getHeader("Content-Type"); 067 } 068 069 @Override /* HttpServletResponse */ 070 public ServletOutputStream getOutputStream() throws IOException { 071 return new FinishableServletOutputStream(baos); 072 } 073 074 @Override /* HttpServletResponse */ 075 public PrintWriter getWriter() throws IOException { 076 return new PrintWriter(new OutputStreamWriter(getOutputStream(), characterEncoding)); 077 } 078 079 @Override /* HttpServletResponse */ 080 public void setCharacterEncoding(String charset) { 081 this.characterEncoding = charset; 082 updateContentTypeHeader(); 083 } 084 085 private void updateContentTypeHeader() { 086 String contentType = getContentType(); 087 String charset = characterEncoding; 088 if (contentType != null && charset != null) { 089 if (contentType.indexOf("charset=") != -1) 090 contentType = contentType.replaceAll("\\;\\s*charset=.*", ""); 091 if (! "UTF-8".equalsIgnoreCase(charset)) 092 contentType = contentType + ";charset=" + charset; 093 header("Content-Type", contentType); 094 } 095 } 096 097 @Override /* HttpServletResponse */ 098 public void setContentLength(int len) { 099 header("Content-Length", String.valueOf(len)); 100 } 101 102 @Override /* HttpServletResponse */ 103 public void setContentLengthLong(long len) { 104 header("Content-Length", String.valueOf(len)); 105 } 106 107 @Override /* HttpServletResponse */ 108 public void setContentType(String type) { 109 setHeader("Content-Type", type); 110 updateContentTypeHeader(); 111 } 112 113 @Override /* HttpServletResponse */ 114 public void setBufferSize(int size) { 115 this.bufferSize = size; 116 } 117 118 @Override /* HttpServletResponse */ 119 public int getBufferSize() { 120 return bufferSize; 121 } 122 123 @Override /* HttpServletResponse */ 124 public void flushBuffer() throws IOException { 125 } 126 127 @Override /* HttpServletResponse */ 128 public void resetBuffer() { 129 } 130 131 @Override /* HttpServletResponse */ 132 public boolean isCommitted() { 133 return false; 134 } 135 136 @Override /* HttpServletResponse */ 137 public void reset() { 138 } 139 140 @Override /* HttpServletResponse */ 141 public void setLocale(Locale loc) { 142 this.locale = loc; 143 } 144 145 @Override /* HttpServletResponse */ 146 public Locale getLocale() { 147 return locale; 148 } 149 150 @Override /* HttpServletResponse */ 151 public void addCookie(Cookie cookie) { 152 } 153 154 @Override /* HttpServletResponse */ 155 public boolean containsHeader(String name) { 156 return getHeader(name) != null; 157 } 158 159 @Override /* HttpServletResponse */ 160 public String encodeURL(String url) { 161 return null; 162 } 163 164 @Override /* HttpServletResponse */ 165 public String encodeRedirectURL(String url) { 166 return null; 167 } 168 169 @Override /* HttpServletResponse */ 170 public String encodeUrl(String url) { 171 return null; 172 } 173 174 @Override /* HttpServletResponse */ 175 public String encodeRedirectUrl(String url) { 176 return null; 177 } 178 179 @Override /* HttpServletResponse */ 180 public void sendError(int sc, String msg) throws IOException { 181 this.sc = sc; 182 this.msg = msg; 183 } 184 185 @Override /* HttpServletResponse */ 186 public void sendError(int sc) throws IOException { 187 this.sc = sc; 188 } 189 190 @Override /* HttpServletResponse */ 191 public void sendRedirect(String location) throws IOException { 192 this.sc = 302; 193 headerMap.put("Location", new String[] {location}); 194 } 195 196 @Override /* HttpServletResponse */ 197 public void setDateHeader(String name, long date) { 198 headerMap.put(name, new String[] {DateUtils.formatDate(new Date(date), DateUtils.PATTERN_RFC1123)}); 199 } 200 201 @Override /* HttpServletResponse */ 202 public void addDateHeader(String name, long date) { 203 headerMap.put(name, new String[] {DateUtils.formatDate(new Date(date), DateUtils.PATTERN_RFC1123)}); 204 } 205 206 @Override /* HttpServletResponse */ 207 public void setHeader(String name, String value) { 208 headerMap.put(name, new String[] {value}); 209 } 210 211 @Override /* HttpServletResponse */ 212 public void addHeader(String name, String value) { 213 headerMap.put(name, new String[] {value}); 214 } 215 216 /** 217 * Fluent setter for {@link #setHeader(String,String)}. 218 * 219 * @param name The header name. 220 * @param value The new header value. 221 * @return This object (for method chaining). 222 */ 223 public MockServletResponse header(String name, String value) { 224 setHeader(name, value); 225 return this; 226 } 227 228 @Override /* HttpServletResponse */ 229 public void setIntHeader(String name, int value) { 230 headerMap.put(name, new String[] {String.valueOf(value)}); 231 } 232 233 @Override /* HttpServletResponse */ 234 public void addIntHeader(String name, int value) { 235 headerMap.put(name, new String[] {String.valueOf(value)}); 236 } 237 238 @Override /* HttpServletResponse */ 239 public void setStatus(int sc) { 240 this.sc = sc; 241 } 242 243 /** 244 * Fluent setter for {@link #setStatus(int)}. 245 * 246 * @param value The new property value. 247 * @return This object (for method chaining). 248 */ 249 public MockServletResponse status(int value) { 250 setStatus(value); 251 return this; 252 } 253 254 @Override /* HttpServletResponse */ 255 public void setStatus(int sc, String sm) { 256 this.sc = sc; 257 this.msg = sm; 258 } 259 260 @Override /* HttpServletResponse */ 261 public int getStatus() { 262 return sc; 263 } 264 265 @Override /* HttpServletResponse */ 266 public String getHeader(String name) { 267 String[] s = headerMap.get(name); 268 return s == null || s.length == 0 ? null : s[0]; 269 } 270 271 @Override /* HttpServletResponse */ 272 public Collection<String> getHeaders(String name) { 273 String[] s = headerMap.get(name); 274 return s == null ? Collections.emptyList() : Arrays.asList(s); 275 } 276 277 @Override /* HttpServletResponse */ 278 public Collection<String> getHeaderNames() { 279 return headerMap.keySet(); 280 } 281 282 byte[] getBody() { 283 return baos.toByteArray(); 284 } 285 286 Map<String,String[]> getHeaders() { 287 return headerMap; 288 } 289}