Package foo.domaintest.action

Source Code of foo.domaintest.action.Response

/**
* Copyright 2014 Google Inc. All rights reserved.
*
* 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 foo.domaintest.action;

import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.net.HttpHeaders.CONNECTION;
import static com.google.common.net.HttpHeaders.LOCATION;
import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import foo.domaintest.action.HttpErrorException.BadRequestException;
import foo.domaintest.metrics.Metrics;
import foo.domaintest.util.Sleeper;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.inject.Inject;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

/** A configurable HTTP response. */
public class Response {

  private static final int MIN_STATUS_CODE = 200;
  private static final int MAX_STATUS_CODE = 499;
  private static final int MAX_SLEEP_SECONDS = 10;

  private final Sleeper sleeper;
  private final HttpServletResponse servletResponse;
  private final Metrics metrics;

  private Integer status;
  private Integer sleepSeconds;
  private String mimeType;
  private List<String> cookiesToDelete;
  private Map<String, String> cookiesToAdd;
  private Map<String, String> headers;
  private String payload;

  @Inject
  public Response(Sleeper sleeper, HttpServletResponse servletResponse, Metrics metrics) {
    this.sleeper = sleeper;
    this.servletResponse = servletResponse;
    this.metrics = metrics;
  }

  public Response setStatus(Integer status) {
    if (status != null
        && (status < MIN_STATUS_CODE || status > MAX_STATUS_CODE)) {
      throw new BadRequestException("Invalid status code (must be >= 200 and < 500)");
    }
    this.status = status;
    return this;
  }

  public Response setSleepSeconds(Integer sleepSeconds) {
    if (sleepSeconds != null
        && (sleepSeconds < 0 || sleepSeconds > MAX_SLEEP_SECONDS)) {
      throw new BadRequestException("Invalid sleep seconds (must be >= 0 and <= 10)");
    }
    this.sleepSeconds = sleepSeconds;
    return this;
  }

  public Response setMimeType(String mimeType) {
    this.mimeType = mimeType;
    return this;
  }

  public Response setCookiesToDelete(List<String> cookiesToDelete) {
    this.cookiesToDelete = cookiesToDelete;
    return this;
  }

  public Response setCookiesToAdd(Map<String, String> cookiesToAdd) {
    this.cookiesToAdd = cookiesToAdd;
    return this;
  }

  public Response setHeaders(Map<String, String> headers) {
    this.headers = headers;
    return this;
  }

  public Response setPayload(String payload) {
    this.payload = payload;
    return this;
  }

  private void setCookie(String name, String value, int maxAge) {
    try {
      Cookie cookie = new Cookie(name, value);
      cookie.setMaxAge(maxAge);
      servletResponse.addCookie(cookie);
    } catch (IllegalArgumentException e) {
      throw new BadRequestException("Illegal cookie", e);
    }
  }

  public void send() {
    setDefaults();
    sleeper.sleep(sleepSeconds);
    servletResponse.setStatus(status);
    for (String cookieToDelete : cookiesToDelete) {
      setCookie(cookieToDelete, "", 0);
      metrics.addActivity("delete_cookie");
    }
    for (Entry<String, String> cookieToAdd : cookiesToAdd.entrySet()) {
      // A maxAge of -1 means session lifetime (goes away when the browser closes).
      setCookie(cookieToAdd.getKey(), cookieToAdd.getValue(), -1);
      metrics.addActivity("add_cookie");
    }
    for (Entry<String, String> header : headers.entrySet()) {
      // Not sure what use header splitting would be since we let you set headers explicitly, but
      // prevent it just in case.
      servletResponse.addHeader(header.getKey(), header.getValue().replaceAll("\n", " "));
      metrics.addActivity("set_header");
    }
    if (status >= 300 && status < 400) {
      // Handle a redirect, if requested.
      // The location should be in the payload field. If it's empty, redirect to the landing page.
      try {
        servletResponse.setHeader(LOCATION, payload.isEmpty()
            ? "/"
            : new URL(payload).toString());
      } catch (MalformedURLException e) {
        throw new BadRequestException("Invalid redirect url", e);
      }
      servletResponse.setHeader(CONNECTION, "close");
    } else {
      servletResponse.setContentType(mimeType);
      try {
        servletResponse.getWriter().write(payload);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
    metrics.setResponseCode(status);
  }

  protected void setDefaults() {
    status = Optional.fromNullable(status).or(HttpServletResponse.SC_OK);
    sleepSeconds = Optional.fromNullable(sleepSeconds).or(0);
    mimeType = Optional.fromNullable(mimeType).or(PLAIN_TEXT_UTF_8.toString());
    cookiesToDelete = Optional.fromNullable(cookiesToDelete).or(ImmutableList.<String>of());
    cookiesToAdd = Optional.fromNullable(cookiesToAdd).or(ImmutableMap.<String, String>of());
    headers = Optional.fromNullable(headers).or(ImmutableMap.<String, String>of());
    payload = nullToEmpty(payload);
  }

  @Override
  public boolean equals(Object other) {
    return other instanceof Response
        && Arrays.equals(getFieldsArray(), ((Response) other).getFieldsArray());
  }

  @Override
  public int hashCode() {
    return Arrays.hashCode(getFieldsArray());
  }

  private Object[] getFieldsArray() {
    return new Object[] {
        status, sleepSeconds, mimeType, cookiesToDelete, cookiesToAdd, headers, payload };
  }
}
TOP

Related Classes of foo.domaintest.action.Response

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.