/* * Copyright (c) 2012. HappyDroids LLC, All rights reserved. */ package com.happydroids.server; import com.badlogic.gdx.Gdx; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.happydroids.HappyDroidConsts; import com.happydroids.jackson.HappyDroidObjectMapper; import org.apach3.http.HttpEntity; import org.apach3.http.HttpResponse; import org.apach3.http.NameValuePair; import org.apach3.http.client.HttpClient; import org.apach3.http.client.cache.CacheResponseStatus; import org.apach3.http.client.methods.HttpGet; import org.apach3.http.client.methods.HttpPost; import org.apach3.http.client.methods.HttpPut; import org.apach3.http.client.methods.HttpRequestBase; import org.apach3.http.client.utils.URLEncodedUtils; import org.apach3.http.conn.HttpHostConnectException; import org.apach3.http.entity.BufferedHttpEntity; import org.apach3.http.entity.StringEntity; import org.apach3.http.impl.client.DefaultHttpClient; import org.apach3.http.impl.client.cache.CacheConfig; import org.apach3.http.impl.client.cache.CachingHttpClient; import org.apach3.http.message.BasicNameValuePair; import org.apach3.http.protocol.BasicHttpContext; import org.apach3.http.util.EntityUtils; import java.net.URI; import java.util.HashMap; import java.util.List; import java.util.Set; import static org.apach3.http.client.cache.CacheResponseStatus.CACHE_HIT; import static org.apach3.http.impl.client.cache.CachingHttpClient.CACHE_RESPONSE_STATUS; public class HappyDroidService { private static final String TAG = HappyDroidService.class.getSimpleName(); protected static HappyDroidService _instance; private static String deviceType; private static String deviceOSVersion; private static String deviceOSMarketName = "none"; private final Set<Runnable> withNetworkConnectionRunnables = Sets.newHashSet(); protected HappyDroidObjectMapper objectMapper; public static HappyDroidService instance() { if (_instance == null) { _instance = new HappyDroidService(); } return _instance; } public static void setInstance(HappyDroidService instance) { HappyDroidService._instance = instance; } protected HappyDroidService() { } protected HappyDroidService(int fuckYouJava) { // leave this for tests. } public static void setDeviceType(String deviceType) { HappyDroidService.deviceType = deviceType; } public static void setDeviceOSMarketName(String deviceOSMarketName) { HappyDroidService.deviceOSMarketName = deviceOSMarketName; } public static void setDeviceOSVersion(String deviceOSVersion) { HappyDroidService.deviceOSVersion = deviceOSVersion; } public static String getDeviceOSVersion() { return deviceOSVersion; } public static String getDeviceOSMarketName() { return deviceOSMarketName; } public static String getDeviceType() { return deviceType; } public HappyDroidObjectMapper getObjectMapper() { if (objectMapper == null) { objectMapper = new HappyDroidObjectMapper(); } return objectMapper; } public static <T> T materializeObject(HttpResponse response, Class<T> aClazz) { ObjectMapper mapper = instance().getObjectMapper(); if (response != null) { try { BufferedHttpEntity entity = new BufferedHttpEntity(response.getEntity()); if (entity != null && entity.getContentLength() > 0) { String content = EntityUtils.toString(entity); if (HappyDroidConsts.DEBUG) { System.out.println("\tResponse: " + content); } return mapper.readValue(content, aClazz); } } catch (Exception e) { throw new RuntimeException(e); } } return null; } public HttpResponse makePutRequest(String uri, Object objectForServer) { HttpClient client = new DefaultHttpClient(); try { if (HappyDroidConsts.DEBUG) { System.out.println("PUT " + uri); } HttpPut request = new HttpPut(uri); addDefaultHeaders(request); if (objectForServer != null) { ObjectMapper mapper = getObjectMapper(); String apiObjectAsString = mapper.writeValueAsString(objectForServer); StringEntity entity = new StringEntity(apiObjectAsString, "UTF-8"); if (HappyDroidConsts.DEBUG) { System.out.println("HTTP ENTITY: " + apiObjectAsString); } entity.setContentType("application/x-www-form-urlencoded"); request.setEntity(entity); } HttpResponse response = client.execute(request); Gdx.app.debug(TAG, "\t" + response.getStatusLine()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != 201 && statusCode != 200) { HttpEntity responseEntity = response.getEntity(); if (responseEntity != null) { String content = EntityUtils.toString(responseEntity); Gdx.app.debug(TAG, "\tResponse: " + content); } else { Gdx.app.debug(TAG, "\tResponse: NULL"); } } return response; } catch (HttpHostConnectException ignored) { if (HappyDroidConsts.DEBUG) { System.out.println("Connection failed for: " + uri); } } catch (Exception e) { e.printStackTrace(); } return null; } public HttpResponse makePostRequest(String uri, Object objectForServer) { HttpClient client = new DefaultHttpClient(); try { Gdx.app.debug(TAG, "POST " + uri); HttpPost request = new HttpPost(uri); addDefaultHeaders(request); if (objectForServer != null) { ObjectMapper mapper = getObjectMapper(); Gdx.app.debug(TAG, "JSON: " + mapper.writeValueAsString(objectForServer)); StringEntity entity = new StringEntity(mapper.writeValueAsString(objectForServer), "UTF-8"); entity.setContentType("application/x-www-form-urlencoded"); request.setEntity(entity); } HttpResponse response = client.execute(request); Gdx.app.debug(TAG, "RES: " + response.getStatusLine()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != 201 && statusCode != 200) { String content = EntityUtils.toString(response.getEntity()); Gdx.app.debug(TAG, "\tResponse: " + content); } return response; } catch (HttpHostConnectException ignored) { Gdx.app.debug(TAG, "Connection failed for: " + uri); throw new RuntimeException(ignored); } catch (Exception e) { throw new RuntimeException(e); } } protected void addDefaultHeaders(HttpRequestBase request) { request.setHeader("Accept-Charset", "utf-8"); request.setHeader("Content-Type", "application/json"); } public HttpResponse makeGetRequest(String url, HashMap<String, String> objectForServer) { return makeGetRequest(url, objectForServer, false, -1); } public HttpResponse makeGetRequest(String urlString, HashMap<String, String> queryParams, boolean enableCache, int cacheMaxAge) { try { URI uri = new URI(urlString); if (queryParams != null && queryParams.size() > 0) { List<NameValuePair> pairs = Lists.newArrayListWithCapacity(queryParams.size()); for (String paramName : queryParams.keySet()) { pairs.add(new BasicNameValuePair(paramName, queryParams.get(paramName))); } uri = new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), URLEncodedUtils.format(pairs, "UTF-8"), uri.getFragment()); } HttpGet request = new HttpGet(uri); addDefaultHeaders(request); Gdx.app.debug(TAG, "REQ: GET " + uri); HttpClient client = new DefaultHttpClient(); if (enableCache) { CacheConfig config = new CacheConfig(); config.setSharedCache(true); config.setMaxCacheEntries(256); config.setMaxObjectSize(10485760); config.setHeuristicCachingEnabled(true); config.setHeuristicDefaultLifetime(cacheMaxAge); client = new CachingHttpClient(client, new HttpCacheDiskStorage(), config); } BasicHttpContext context = new BasicHttpContext(); HttpResponse response = client.execute(request, context); CacheResponseStatus responseStatus = (CacheResponseStatus) context.getAttribute(CACHE_RESPONSE_STATUS); if (responseStatus == CACHE_HIT) { Gdx.app.debug(TAG, "CACHED: GET " + uri + ", " + response.getStatusLine()); } else { Gdx.app.debug(TAG, "RES: GET " + uri + ", " + response.getStatusLine()); } return response; } catch (Exception ignored) { Gdx.app.error(TAG, "Connection failed for: " + urlString, ignored); throw new RuntimeException(ignored); } } public String getDeviceId() { return null; } public boolean isAuthenticated() { return false; } }