All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.sitebricks.headless.NettyReplyMaker Maven / Gradle / Ivy

package com.google.sitebricks.headless;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.sitebricks.client.Transport;
import com.google.sitebricks.rendering.Templates;
import org.apache.commons.io.IOUtils;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;
import org.jboss.netty.util.CharsetUtil;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map.Entry;

/**
 * Sits here so it is able to access the internals of ReplyMaker.
 *
 * @author [email protected] (Dhanji R. Prasanna)
 */
@Singleton
public class NettyReplyMaker {
  private final Injector injector;

  @Inject
  public NettyReplyMaker(Injector injector) {
    this.injector = injector;
  }

  public  HttpResponse populate(Reply o) throws IOException {
    // Should be enforced by the Sitebricks page validator.
    assert o instanceof ReplyMaker;

    ReplyMaker reply = (ReplyMaker) o;
    DefaultHttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
        HttpResponseStatus.valueOf(reply.status));

    Transport transport = injector.getInstance(reply.transport);

    if (!reply.headers.isEmpty()) {
      for (Entry entry : reply.headers.entrySet()) {
        response.setHeader(entry.getKey(), entry.getValue());
      }
    }

    // By default we use the content type of the transport.
    if (null == reply.contentType) {
      response.setHeader(Names.CONTENT_TYPE, transport.contentType());
    } else {
      response.setHeader(Names.CONTENT_TYPE, reply.contentType);
    }

    if (null != reply.redirectUri) {
      response.setHeader(Names.LOCATION, reply.redirectUri);
      return response;
    }

    // Write the entity data to our output buffer.
    if (null != reply.templateKey) {
      String output = injector.getInstance(Templates.class).render(reply.templateKey,
          reply.entity);
      response.setContent(ChannelBuffers.copiedBuffer(output, CharsetUtil.UTF_8));
    } else if (null != reply.entity) {
      if (reply.entity instanceof InputStream) {
        // Buffer the stream and write it, rather than marshalling it through a transport.
        // Note this exists for compatibility with the sync model, and can be quite expensive.
        InputStream inputStream = (InputStream) reply.entity;
        try {
          byte[] bytes = IOUtils.toByteArray(inputStream);
          response.setContent(ChannelBuffers.copiedBuffer(bytes));
        } finally {
          inputStream.close();
        }
      } else {
        // TODO(dhanji): This feels wrong to me. We need a better way to obtain the entity type.
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        transport.out(out, (Class) reply.entity.getClass(), reply.entity);
        response.setContent(ChannelBuffers.copiedBuffer(out.toByteArray()));
      }
    }

    return response;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy