Package com.google.sitebricks.headless

Source Code of com.google.sitebricks.headless.ReplyMaker

package com.google.sitebricks.headless;

import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.io.ByteStreams;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.sitebricks.client.Transport;
import com.google.sitebricks.client.transport.Text;
import com.google.sitebricks.rendering.Strings;
import com.google.sitebricks.rendering.Templates;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

/**
* A builder implementation of the Reply interface.
*/
class ReplyMaker<E> extends Reply<E> {

  // By default, we cool.
  int status = HttpServletResponse.SC_OK;

  String contentType;

  String redirectUri;
  Map<String, String> headers = Maps.newHashMap();

  Key<? extends Transport> transport = Key.get(Text.class);
  E entity;
  Class<?> templateKey;

  public ReplyMaker(E entity) {
    this.entity = entity;
  }

  @Override
  public Reply<E> seeOther(String uri) {
    redirectUri = uri;
    status = HttpServletResponse.SC_MOVED_PERMANENTLY;
    return this;
  }

  @Override
  public Reply<E> seeOther(String uri, int statusCode) {
    Preconditions.checkArgument(statusCode >= 300 && statusCode < 400,
        "Redirect statuses must be between 300-399");
    redirectUri = uri;
    status = statusCode;
    return this;
  }

  @Override
  public Reply<E> type(String mediaType) {
    Strings.nonEmpty(mediaType, "Media type cannot be null or empty");
    this.contentType = mediaType;
    return this;
  }

  @Override
  public Reply<E> headers(Map<String, String> headers) {
    this.headers.putAll(headers);
    return this;
  }

  @Override
  public Reply<E> notFound() {
    status = HttpServletResponse.SC_NOT_FOUND;
    return this;
  }

  @Override
  public Reply<E> unauthorized() {
    status = HttpServletResponse.SC_UNAUTHORIZED;
    return this;
  }

  @Override
  public Reply<E> as(Key<? extends Transport> transport) {
    Preconditions.checkArgument(null != transport, "Transport class cannot be null!");
    this.transport = transport;
    return this;
  }

  @Override
  public Reply<E> as(Class<? extends Transport> transport) {
    Preconditions.checkArgument(null != transport, "Transport class cannot be null!");
    this.transport = Key.get(transport);
    return this;
  }

  @Override
  public Reply<E> redirect(String url) {
    Strings.nonEmpty(url, "Redirect URL must be non empty!");
    this.redirectUri = url;
    status = HttpServletResponse.SC_MOVED_TEMPORARILY;
    return this;
  }

  @Override
  public Reply<E> forbidden() {
    status = HttpServletResponse.SC_FORBIDDEN;
    return this;
  }

  @Override
  public Reply<E> noContent() {
    status = HttpServletResponse.SC_NO_CONTENT;
    return this;
  }

  @Override
  public Reply<E> error() {
    status = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
    return this;
  }

  @Override
  public Reply<E> badRequest() {
    status = HttpServletResponse.SC_BAD_REQUEST;
    return this;
  }

  @Override
  public Reply<E> status(int code) {
    status = code;
    return this;
  }

  @Override
  public Reply<E> ok() {
    status = HttpServletResponse.SC_OK;
    return this;
  }

  @Override
  public Reply<E> template(Class<?> templateKey) {
    this.templateKey = templateKey;
    return this;
  }

  @Override @SuppressWarnings("unchecked")
  void populate(Injector injector, HttpServletResponse response) throws IOException {
    // If we should not bother with the chain
    if (Reply.NO_REPLY == this) {
      injector.getInstance(HttpServletRequest.class).setAttribute(Reply.NO_REPLY_ATTR, Boolean.TRUE);
      return;
    }

    // This is where we take all the builder values and encode them in the response.
    Transport transport = injector.getInstance(this.transport);

    // Set any headers (we do this first, so we can override any cheekily set headers).
    if (!headers.isEmpty()) {
      for (Map.Entry<String, String> header : headers.entrySet()) {
        response.setHeader(header.getKey(), header.getValue());
      }
    }

    // If the content type was already set, do nothing.
    if (response.getContentType() == null) {
      // By default we use the content type of the transport.
      if (null == contentType) {
        response.setContentType(transport.contentType());
      } else {
        response.setContentType(contentType);
      }
    }

    // Send redirect
    if (null != redirectUri) {
      response.sendRedirect(redirectUri);
      response.setStatus(status); // HACK to override whatever status the redirect sets.
      return;
    }

    // Write out data.
    response.setStatus(status);

    if (null != templateKey) {
      response.getWriter().write(injector.getInstance(Templates.class).render(templateKey, entity));
    } else if (null != entity) {
      if (entity instanceof InputStream) {
        // Stream the response rather than marshalling it through a transport.
        InputStream inputStream = (InputStream) entity;
        try {
          ByteStreams.copy(inputStream, response.getOutputStream());
        } finally {
          inputStream.close();
        }
      } else {
        // TODO(dhanji): This feels wrong to me. We need a better way to obtain the entity type.
        transport.out(response.getOutputStream(), (Class<E>) entity.getClass(), entity);
      }
    }
  }
 
  @Override
  public boolean equals(Object other) {
    if(!(other instanceof ReplyMaker<?>))
      return false;
   
    @SuppressWarnings("unchecked")
    ReplyMaker<E> o = (ReplyMaker<E>)other;
    if(this.status != o.status)
      return false;
   
    if((this.contentType != o.contentType)
    && (this.contentType != null && !this.contentType.equals(o.contentType))
    && (this.contentType == null && o.contentType != null))
      return false;
   
    if((this.redirectUri != o.redirectUri)
    && (this.redirectUri != null && !this.redirectUri.equals(o.redirectUri))
    && (this.redirectUri == null && o.redirectUri != null))
      return false;
       
    if(!this.headers.equals(o.headers))
      return false;
   
    if(!this.transport.equals(o.transport))
      return false;
   
    if(this.templateKey != o.templateKey)
      return false;

    if((this.entity != o.entity)
    && (this.entity != null && !this.entity.equals(o.entity))
    && (this.entity == null && o.entity != null))
      return false;
   
    // All tests passed, the objects must be equal
    return true;
  }
}
TOP

Related Classes of com.google.sitebricks.headless.ReplyMaker

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.