Package com.google.sitebricks

Source Code of com.google.sitebricks.ServletRequestProvider

package com.google.sitebricks;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;

import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.google.common.io.ByteStreams;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
import com.google.sitebricks.client.Transport;
import com.google.sitebricks.headless.Request;
import com.google.sitebricks.http.Parameters;
import com.google.sitebricks.validation.SitebricksValidator;

/**
* @author dhanji@gmail.com (Dhanji R. Prasanna)
*/
@Singleton
class ServletRequestProvider implements Provider<Request<String>> {
  private final Provider<HttpServletRequest> servletRequest;
  private final Injector injector;
  private final SitebricksValidator validator;

  @Inject
  public ServletRequestProvider(Provider<HttpServletRequest> servletRequest, Injector injector,
          SitebricksValidator validator) {
    this.servletRequest = servletRequest;
    this.injector = injector;
    this.validator = validator;
  }

  @Override
  public Request<String> get() {
    return new Request<String>() {
      HttpServletRequest servletRequest = ServletRequestProvider.this.servletRequest.get();
      Multimap<String, String> matrix;
      Multimap<String, String> headers;
      Multimap<String, String> params;
      String method;

      @Override
      public <E> RequestRead<E> read(final Class<E> type) {
        return new RequestRead<E>() {
          E memo;

          @Override
          public E as(Class<? extends Transport> transport) {
            try {
              // Only read from the stream once.
              if (null == memo) {
                memo = injector.getInstance(transport).in(servletRequest.getInputStream(),
                    type);
              }
            } catch (IOException e) {
              throw new RuntimeException("Unable to obtain input stream from servlet request" +
                  " (was it already used or closed elsewhere?). Error:\n" + e.getMessage(), e);
            }

            return memo;
          }
        };
      }

      @Override
      public <E> RequestRead<E> read(final TypeLiteral<E> type) {
        return new RequestRead<E>() {
          E memo;

          @Override
          public E as(Class<? extends Transport> transport) {
            try {
              // Only read from the stream once.
              if (null == memo) {
                memo = injector.getInstance(transport).in(servletRequest.getInputStream(),
                    type);
              }
            } catch (IOException e) {
              throw new RuntimeException("Unable to obtain input stream from servlet request" +
                  " (was it already used or closed elsewhere?). Error:\n" + e.getMessage(), e);
            }

            return memo;
          }
        };
      }

      @Override
      public void readTo(OutputStream out) throws IOException {
        ByteStreams.copy(servletRequest.getInputStream(), out);
      }

      @Override
      public Multimap<String, String> headers() {
        if (null == headers) {
          readHeaders();
        }
        return headers;
      }

      @Override
      public Multimap<String, String> params() {
        if (null == params) {
          readParams();
        }
        return params;
      }

      @Override
      public Multimap<String, String> matrix() {
        if (null == matrix) {
          this.matrix = Parameters.readMatrix(servletRequest.getRequestURI());
        }
        return matrix;
      }

      @Override
      public String matrixParam(String name) {
        if (null == matrix) {
          this.matrix = Parameters.readMatrix(servletRequest.getRequestURI());
        }
        return Parameters.singleMatrixParam(name, matrix.get(name));
      }

      @Override
      public String param(String name) {
        return servletRequest.getParameter(name);
      }

      @Override
      public String header(String name) {
        return servletRequest.getHeader(name);
      }

      @Override public String uri() {
        return servletRequest.getRequestURI();
      }

      @Override public String path() {
        return servletRequest.getRequestURI().substring(servletRequest.getContextPath().length());
      }

      @Override public String context() {
        return servletRequest.getContextPath();
      }

      @Override public String method() {
        // This ugly hack is required because Sitebricks supports simulating PUT/DELETE requests
        // via browser POST and special form fields.
        if (method == null) {
          String ghostMethod = servletRequest.getParameter(HiddenMethodFilter.hiddenFieldName);
          method = (ghostMethod != null) ? ghostMethod : servletRequest.getMethod();
        }
        return method;
      }

      @Override
      public void validate(Object object) {
          Set<? extends ConstraintViolation<?>> cvs = validator.validate(object);
          if ((cvs != null) && (! cvs.isEmpty())) {
              throw new ValidationException(new ConstraintViolationException((Set<ConstraintViolation<?>>) cvs));
          }
      }

    private void readParams() {
        ImmutableMultimap.Builder<String, String> builder = ImmutableMultimap.builder();

        @SuppressWarnings("unchecked") // Guaranteed by servlet spec
            Map<String, String[]> parameterMap = servletRequest.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
          builder.putAll(entry.getKey(), entry.getValue());
        }

        this.params = builder.build();
      }

      private void readHeaders() {
        // Build once per request only (so do it here).
        ImmutableMultimap.Builder<String, String> builder = ImmutableMultimap.builder();

        @SuppressWarnings("unchecked") // Guaranteed by servlet spec
            Enumeration<String> headerNames = servletRequest.getHeaderNames();
        while (headerNames.hasMoreElements()) {
          String header = headerNames.nextElement();

          @SuppressWarnings("unchecked") // Guaranteed by servlet spec
          Enumeration<String> values = servletRequest.getHeaders(header);
          while (values.hasMoreElements()) {
            builder.put(header, values.nextElement());
          }
        }

        this.headers = builder.build();
      }

    };

  }
 
}
TOP

Related Classes of com.google.sitebricks.ServletRequestProvider

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.