package restx.server.simple.simple; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.simpleframework.http.Cookie; import org.simpleframework.http.Query; import org.simpleframework.http.Request; import restx.AbstractRequest; import restx.HttpSettings; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; /** * User: xavierhanin * Date: 2/16/13 * Time: 1:57 PM */ public class SimpleRestxRequest extends AbstractRequest { private final String restxPath; private final String apiPath; private final Request request; private BufferedInputStream bufferedInputStream; private ImmutableMap<String, ImmutableList<String>> queryParams; public SimpleRestxRequest(HttpSettings httpSettings, String apiPath, Request request) { super(httpSettings); this.apiPath = apiPath; this.request = request; String path = request.getTarget().substring(apiPath.length()); if (path.indexOf("?") != -1) { path = path.substring(0, path.indexOf("?")); } this.restxPath = path; } @Override protected String getBaseApiPath() { return apiPath; } @Override protected String getLocalScheme() { return request.isSecure() ? "https" : "http"; } @Override public String getLocalClientAddress() { return request.getClientAddress().getAddress().getHostAddress(); } @Override public String getRestxPath() { return restxPath; } @Override public String getRestxUri() { return getRestxPath() + (request.getQuery().isEmpty() ? "" : "?" + request.getQuery().toString()); } @Override public String getHttpMethod() { return request.getMethod(); } @Override public Optional<String> getQueryParam(String param) { return Optional.fromNullable(request.getQuery().get(param)); } @Override public List<String> getQueryParams(String param) { List<String> queryParams = request.getQuery().getAll(param); return queryParams==null?null:Lists.newArrayList(queryParams); } @Override public ImmutableMap<String, ImmutableList<String>> getQueryParams() { if (queryParams == null) { ImmutableMap.Builder<String, ImmutableList<String>> paramsBuilder = ImmutableMap.builder(); Query query = request.getQuery(); for (String param : query.keySet()) { paramsBuilder.put(param, ImmutableList.copyOf(query.getAll(param))); } queryParams = paramsBuilder.build(); } return queryParams; } @Override public Optional<String> getHeader(String headerName) { return Optional.fromNullable(request.getValue(headerName)); } @Override public String getContentType() { return request.getContentType().getType(); } @Override public ImmutableMap<String, String> getCookiesMap() { Map<String, String> cookies = Maps.newLinkedHashMap(); for (Cookie cookie : request.getCookies()) { cookies.put(cookie.getName(), cookie.getValue().replace("\\\"", "\"")); } return ImmutableMap.copyOf(cookies); } @Override public Optional<String> getCookieValue(String cookieName) { return Optional.fromNullable(getCookiesMap().get(cookieName)); } @Override public boolean isPersistentCookie(String cookie) { Map<String, String> cookiesMap = getCookiesMap(); return cookiesMap.containsKey(cookie) ? request.getCookie(cookie).getExpiry() > 0 : false; } @Override public InputStream getContentStream() throws IOException { /* maybe we could do this buffering only in dev mode? It is used to be able to read data again in case of json processing error. */ if (bufferedInputStream == null) { bufferedInputStream = new BufferedInputStream(request.getInputStream()) { @Override public void close() throws IOException { // NO OP, see #closeContentStream } }; bufferedInputStream.mark(10 * 1024); } return bufferedInputStream; } @Override public void closeContentStream() throws IOException { bufferedInputStream.close(); } @Override @SuppressWarnings("unchecked") public <T> T unwrap(Class<T> clazz) { if (clazz == Request.class) { return (T) request; } throw new IllegalArgumentException("underlying implementation is " + Request.class.getName() + ", not " + clazz.getName()); } @Override public Locale getLocale() { if (request.getLocales() != null && !request.getLocales().isEmpty()) { return request.getLocales().get(0); } return Locale.getDefault(); } @Override public ImmutableList<Locale> getLocales() { List<Locale> locales = request.getLocales(); if (locales.isEmpty()) { return ImmutableList.of(Locale.getDefault()); } else { return ImmutableList.copyOf(locales); } } }