aboutsummaryrefslogtreecommitdiff
path: root/libs/networking/WordPressNetworking
diff options
context:
space:
mode:
Diffstat (limited to 'libs/networking/WordPressNetworking')
-rw-r--r--libs/networking/WordPressNetworking/build.gradle49
-rw-r--r--libs/networking/WordPressNetworking/gradle.properties-example2
-rw-r--r--libs/networking/WordPressNetworking/src/main/AndroidManifest.xml3
-rw-r--r--libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/Authenticator.java13
-rw-r--r--libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/AuthenticatorRequest.java96
-rw-r--r--libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactory.java19
-rw-r--r--libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactoryAbstract.java9
-rw-r--r--libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactoryDefault.java14
-rw-r--r--libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientUtils.java475
9 files changed, 680 insertions, 0 deletions
diff --git a/libs/networking/WordPressNetworking/build.gradle b/libs/networking/WordPressNetworking/build.gradle
new file mode 100644
index 000000000..c0e937773
--- /dev/null
+++ b/libs/networking/WordPressNetworking/build.gradle
@@ -0,0 +1,49 @@
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.2.0'
+ }
+}
+
+repositories {
+ jcenter()
+ maven { url 'http://wordpress-mobile.github.io/WordPress-Android' }
+}
+
+apply plugin: 'com.android.library'
+apply plugin: 'maven'
+
+android {
+ publishNonDefault true
+
+ compileSdkVersion 24
+ buildToolsVersion "24.0.2"
+
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 24
+ versionName "1.0.0"
+ }
+}
+
+dependencies {
+ compile 'org.wordpress:utils:1.11.0'
+ compile 'com.automattic:rest:1.0.7'
+}
+
+uploadArchives {
+ repositories {
+ mavenDeployer {
+ def repo_url = ""
+ if (project.hasProperty("repository")) {
+ repo_url = project.repository
+ }
+ repository(url: repo_url)
+ pom.version = android.defaultConfig.versionName
+ pom.groupId = "org.wordpress"
+ pom.artifactId = "wordpress-networking"
+ }
+ }
+}
diff --git a/libs/networking/WordPressNetworking/gradle.properties-example b/libs/networking/WordPressNetworking/gradle.properties-example
new file mode 100644
index 000000000..5a17295c3
--- /dev/null
+++ b/libs/networking/WordPressNetworking/gradle.properties-example
@@ -0,0 +1,2 @@
+wp.db_secret = wordpress
+repository = file:///Users/max/work/automattic/WordPress-Android-gh-pages/
diff --git a/libs/networking/WordPressNetworking/src/main/AndroidManifest.xml b/libs/networking/WordPressNetworking/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..f19a8bd89
--- /dev/null
+++ b/libs/networking/WordPressNetworking/src/main/AndroidManifest.xml
@@ -0,0 +1,3 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.wordpress.android.networking">
+</manifest>
diff --git a/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/Authenticator.java b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/Authenticator.java
new file mode 100644
index 000000000..cf7bd78bb
--- /dev/null
+++ b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/Authenticator.java
@@ -0,0 +1,13 @@
+package org.wordpress.android.networking;
+
+/**
+ * Interface that provides a method that should perform the necessary task to make sure
+ * the provided AuthenticatorRequest will be authenticated.
+ *
+ * The Authenticator must call AuthenticatorRequest.send() when it has completed its operations. For
+ * convenience the AuthenticatorRequest class provides AuthenticatorRequest.setAccessToken so the Authenticator can
+ * easily update the access token.
+ */
+public interface Authenticator {
+ void authenticate(final AuthenticatorRequest authenticatorRequest);
+}
diff --git a/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/AuthenticatorRequest.java b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/AuthenticatorRequest.java
new file mode 100644
index 000000000..40d2af7f3
--- /dev/null
+++ b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/AuthenticatorRequest.java
@@ -0,0 +1,96 @@
+package org.wordpress.android.networking;
+
+import com.android.volley.VolleyError;
+import com.wordpress.rest.Oauth;
+import com.wordpress.rest.RestClient;
+import com.wordpress.rest.RestRequest;
+import com.wordpress.rest.RestRequest.ErrorListener;
+
+/**
+ * Encapsulates the behaviour for asking the Authenticator for an access token. This
+ * allows the request maker to disregard the authentication state when making requests.
+ */
+public class AuthenticatorRequest {
+ private RestRequest mRequest;
+ private RestRequest.ErrorListener mListener;
+ private RestClient mRestClient;
+ private Authenticator mAuthenticator;
+
+ protected AuthenticatorRequest(RestRequest request, ErrorListener listener, RestClient restClient,
+ Authenticator authenticator) {
+ mRequest = request;
+ mListener = listener;
+ mRestClient = restClient;
+ mAuthenticator = authenticator;
+ }
+
+ public String getSiteId() {
+ return extractSiteIdFromUrl(mRestClient.getEndpointURL(), mRequest.getUrl());
+ }
+
+ /**
+ * Parse out the site ID from an URL.
+ * Note: For batch REST API calls, only the first siteID is returned
+ *
+ * @return The site ID
+ */
+ public static String extractSiteIdFromUrl(String restEndpointUrl, String url) {
+ if (url == null) {
+ return null;
+ }
+
+ final String sitePrefix = restEndpointUrl.endsWith("/") ? restEndpointUrl + "sites/" : restEndpointUrl + "/sites/";
+ final String batchCallPrefix = restEndpointUrl.endsWith("/") ? restEndpointUrl + "batch/?urls%5B%5D=%2Fsites%2F"
+ : restEndpointUrl + "/batch/?urls%5B%5D=%2Fsites%2F";
+
+ if (url.startsWith(sitePrefix) && !sitePrefix.equals(url)) {
+ int marker = sitePrefix.length();
+ if (url.indexOf("/", marker) < marker) {
+ return null;
+ }
+ return url.substring(marker, url.indexOf("/", marker));
+ } else if (url.startsWith(batchCallPrefix) && !batchCallPrefix.equals(url)) {
+ int marker = batchCallPrefix.length();
+ if (url.indexOf("%2F", marker) < marker) {
+ return null;
+ }
+ return url.substring(marker, url.indexOf("%2F", marker));
+ }
+
+ // not a sites/$siteId request or a batch request
+ return null;
+ }
+
+ /**
+ * Attempt to send the request, checks to see if we have an access token and if not
+ * asks the Authenticator to authenticate the request.
+ *
+ * If no Authenticator is provided the request is always sent.
+ */
+ protected void send(){
+ if (mAuthenticator == null) {
+ mRestClient.send(mRequest);
+ } else {
+ mAuthenticator.authenticate(this);
+ }
+ }
+
+ public void sendWithAccessToken(String token){
+ mRequest.setAccessToken(token);
+ mRestClient.send(mRequest);
+ }
+
+ public void sendWithAccessToken(Oauth.Token token){
+ sendWithAccessToken(token.toString());
+ }
+
+ /**
+ * If an access token cannot be obtained the request can be aborted and the
+ * handler's onFailure method is called
+ */
+ public void abort(VolleyError error){
+ if (mListener != null) {
+ mListener.onErrorResponse(error);
+ }
+ }
+}
diff --git a/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactory.java b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactory.java
new file mode 100644
index 000000000..492b2b99f
--- /dev/null
+++ b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactory.java
@@ -0,0 +1,19 @@
+package org.wordpress.android.networking;
+
+import com.android.volley.RequestQueue;
+import com.wordpress.rest.RestClient;
+
+public class RestClientFactory {
+ private static RestClientFactoryAbstract sFactory;
+
+ public static RestClient instantiate(RequestQueue queue) {
+ return instantiate(queue, RestClient.REST_CLIENT_VERSIONS.V1);
+ }
+
+ public static RestClient instantiate(RequestQueue queue, RestClient.REST_CLIENT_VERSIONS version) {
+ if (sFactory == null) {
+ sFactory = new RestClientFactoryDefault();
+ }
+ return sFactory.make(queue, version);
+ }
+}
diff --git a/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactoryAbstract.java b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactoryAbstract.java
new file mode 100644
index 000000000..799a5a8e8
--- /dev/null
+++ b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactoryAbstract.java
@@ -0,0 +1,9 @@
+package org.wordpress.android.networking;
+
+import com.android.volley.RequestQueue;
+import com.wordpress.rest.RestClient;
+
+public interface RestClientFactoryAbstract {
+ public RestClient make(RequestQueue queue);
+ public RestClient make(RequestQueue queue, RestClient.REST_CLIENT_VERSIONS version);
+}
diff --git a/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactoryDefault.java b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactoryDefault.java
new file mode 100644
index 000000000..b87d4b40f
--- /dev/null
+++ b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientFactoryDefault.java
@@ -0,0 +1,14 @@
+package org.wordpress.android.networking;
+
+import com.android.volley.RequestQueue;
+import com.wordpress.rest.RestClient;
+
+public class RestClientFactoryDefault implements RestClientFactoryAbstract {
+ public RestClient make(RequestQueue queue) {
+ return new RestClient(queue);
+ }
+
+ public RestClient make(RequestQueue queue, RestClient.REST_CLIENT_VERSIONS version) {
+ return new RestClient(queue, version);
+ }
+}
diff --git a/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientUtils.java b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientUtils.java
new file mode 100644
index 000000000..6e06cfeee
--- /dev/null
+++ b/libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientUtils.java
@@ -0,0 +1,475 @@
+/**
+ * Interface to the WordPress.com REST API.
+ */
+package org.wordpress.android.networking;
+
+import android.content.Context;
+import android.net.Uri;
+import android.text.TextUtils;
+
+import com.android.volley.DefaultRetryPolicy;
+import com.android.volley.Request;
+import com.android.volley.Request.Method;
+import com.android.volley.RequestQueue;
+import com.android.volley.RetryPolicy;
+import com.android.volley.toolbox.RequestFuture;
+import com.wordpress.rest.JsonRestRequest;
+import com.wordpress.rest.RestClient;
+import com.wordpress.rest.RestRequest;
+import com.wordpress.rest.RestRequest.ErrorListener;
+import com.wordpress.rest.RestRequest.Listener;
+
+import org.json.JSONObject;
+import org.wordpress.android.util.LanguageUtils;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeoutException;
+
+public class RestClientUtils {
+ private static final String NOTIFICATION_FIELDS = "id,type,unread,body,subject,timestamp,meta";
+ private static final String COMMENT_REPLY_CONTENT_FIELD = "content";
+ private static String sUserAgent = "WordPress Networking Android";
+
+ private RestClient mRestClient;
+ private Authenticator mAuthenticator;
+ private Context mContext;
+
+ /**
+ * Socket timeout in milliseconds for rest requests
+ */
+ public static final int REST_TIMEOUT_MS = 30000;
+
+ /**
+ * Default number of retries for POST rest requests
+ */
+ public static final int REST_MAX_RETRIES_POST = 0;
+
+ /**
+ * Default number of retries for GET rest requests
+ */
+ public static final int REST_MAX_RETRIES_GET = 3;
+
+ /**
+ * Default backoff multiplier for rest requests
+ */
+ public static final float REST_BACKOFF_MULT = 2f;
+
+ public static void setUserAgent(String userAgent) {
+ sUserAgent = userAgent;
+ }
+
+ public RestClientUtils(Context context, RequestQueue queue, Authenticator authenticator, RestRequest.OnAuthFailedListener onAuthFailedListener) {
+ this(context, queue, authenticator, onAuthFailedListener, RestClient.REST_CLIENT_VERSIONS.V1);
+ }
+
+ public RestClientUtils(Context context, RequestQueue queue, Authenticator authenticator, RestRequest.OnAuthFailedListener onAuthFailedListener, RestClient.REST_CLIENT_VERSIONS version) {
+ // load an existing access token from prefs if we have one
+ mContext = context;
+ mAuthenticator = authenticator;
+ mRestClient = RestClientFactory.instantiate(queue, version);
+ if (onAuthFailedListener != null) {
+ mRestClient.setOnAuthFailedListener(onAuthFailedListener);
+ }
+ mRestClient.setUserAgent(sUserAgent);
+ }
+
+ public Authenticator getAuthenticator() {
+ return mAuthenticator;
+ }
+
+ public RestClient getRestClient() {
+ return mRestClient;
+ }
+
+ public void getCategories(String siteId, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/categories", siteId);
+ get(path, null, null, listener, errorListener);
+ }
+
+ /**
+ * get a list of recent comments
+ * <p/>
+ * https://developer.wordpress.com/docs/api/1.1/get/sites/%24site/comments/
+ */
+ public void getComments(String siteId, Map<String, String> params, final Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/comments", siteId);
+ get(path, params, null, listener, errorListener);
+ }
+
+ /**
+ * Reply to a comment
+ * <p/>
+ * https://developer.wordpress.com/docs/api/1/post/sites/%24site/posts/%24post_ID/replies/new/
+ */
+ public void replyToComment(String reply, String path, Listener listener, ErrorListener errorListener) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put(COMMENT_REPLY_CONTENT_FIELD, reply);
+ post(path, params, null, listener, errorListener);
+ }
+
+ /**
+ * Reply to a comment.
+ * <p/>
+ * https://developer.wordpress.com/docs/api/1/post/sites/%24site/posts/%24post_ID/replies/new/
+ */
+ public void replyToComment(long siteId, long commentId, String content, Listener listener,
+ ErrorListener errorListener) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put(COMMENT_REPLY_CONTENT_FIELD, content);
+ String path = String.format("sites/%d/comments/%d/replies/new", siteId, commentId);
+ post(path, params, null, listener, errorListener);
+ }
+
+ /**
+ * Follow a site given an ID or domain
+ * <p/>
+ * https://developer.wordpress.com/docs/api/1/post/sites/%24site/follows/new/
+ */
+ public void followSite(String siteId, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/follows/new", siteId);
+ post(path, listener, errorListener);
+ }
+
+ /**
+ * Unfollow a site given an ID or domain
+ * <p/>
+ * https://developer.wordpress.com/docs/api/1/post/sites/%24site/follows/mine/delete/
+ */
+ public void unfollowSite(String siteId, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/follows/mine/delete", siteId);
+ post(path, listener, errorListener);
+ }
+
+ /**
+ * Get notifications with the provided params.
+ * <p/>
+ * https://developer.wordpress.com/docs/api/1/get/notifications/
+ */
+ public void getNotifications(Map<String, String> params, Listener listener, ErrorListener errorListener) {
+ params.put("number", "40");
+ params.put("num_note_items", "20");
+ params.put("fields", NOTIFICATION_FIELDS);
+ get("notifications", params, null, listener, errorListener);
+ }
+
+ /**
+ * Get notifications with default params.
+ * <p/>
+ * https://developer.wordpress.com/docs/api/1/get/notifications/
+ */
+ public void getNotifications(Listener listener, ErrorListener errorListener) {
+ getNotifications(new HashMap<String, String>(), listener, errorListener);
+ }
+
+ /**
+ * Update the seen timestamp.
+ * <p/>
+ * https://developer.wordpress.com/docs/api/1/post/notifications/seen
+ */
+ public void markNotificationsSeen(String timestamp, Listener listener, ErrorListener errorListener) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put("time", timestamp);
+ post("notifications/seen", params, null, listener, errorListener);
+ }
+
+ /**
+ * Moderate a comment.
+ * <p/>
+ * http://developer.wordpress.com/docs/api/1/sites/%24site/comments/%24comment_ID/
+ */
+ public void moderateComment(String siteId, String commentId, String status, Listener listener,
+ ErrorListener errorListener) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put("status", status);
+ String path = String.format("sites/%s/comments/%s/", siteId, commentId);
+ post(path, params, null, listener, errorListener);
+ }
+
+ /**
+ * Edit the content of a comment
+ */
+ public void editCommentContent(long siteId, long commentId, String content, Listener listener,
+ ErrorListener errorListener) {
+ Map<String, String> params = new HashMap<String, String>();
+ params.put("content", content);
+ String path = String.format("sites/%d/comments/%d/", siteId, commentId);
+ post(path, params, null, listener, errorListener);
+ }
+
+ /**
+ * Like or unlike a comment.
+ */
+ public void likeComment(String siteId, String commentId, boolean isLiked, Listener listener,
+ ErrorListener errorListener) {
+ Map<String, String> params = new HashMap<String, String>();
+ String path = String.format("sites/%s/comments/%s/likes/", siteId, commentId);
+
+ if (!isLiked) {
+ path += "mine/delete";
+ } else {
+ path += "new";
+ }
+
+ post(path, params, null, listener, errorListener);
+ }
+
+ public void getFreeSearchThemes(String siteId, int limit, int offset, String searchTerm, Listener listener, ErrorListener errorListener) {
+ getSearchThemes("free", siteId, limit, offset, searchTerm, listener, errorListener);
+ }
+
+ public void getSearchThemes(String tier, String siteId, int limit, int offset, String searchTerm, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/themes?tier=" + tier + "&number=%d&offset=%d&search=%s", siteId, limit, offset, searchTerm);
+ get(path, listener, errorListener);
+ }
+
+ public void getFreeThemes(String siteId, int limit, int offset, Listener listener, ErrorListener errorListener) {
+ getThemes("free", siteId, limit, offset, listener, errorListener);
+ }
+
+ public void getPurchasedThemes(String siteId, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/themes/purchased", siteId);
+ get(path, listener, errorListener);
+ }
+
+ /**
+ * Get all a site's themes
+ */
+ public void getThemes(String tier, String siteId, int limit, int offset, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/themes/?tier=" + tier + "&number=%d&offset=%d", siteId, limit, offset);
+ get(path, listener, errorListener);
+ }
+
+ /**
+ * Set a site's theme
+ */
+ public void setTheme(String siteId, String themeId, Listener listener, ErrorListener errorListener) {
+ Map<String, String> params = new HashMap<>();
+ params.put("theme", themeId);
+ String path = String.format("sites/%s/themes/mine", siteId);
+ post(path, params, null, listener, errorListener);
+ }
+
+ /**
+ * Get a site's current theme
+ */
+ public void getCurrentTheme(String siteId, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/themes/mine", siteId);
+ get(path, listener, errorListener);
+ }
+
+ public void getGeneralSettings(String siteId, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/settings", siteId);
+ Map<String, String> params = new HashMap<String, String>();
+ get(path, params, null, listener, errorListener);
+ }
+
+ public void setGeneralSiteSettings(String siteId, Listener listener, ErrorListener errorListener,
+ Map<String, String> params) {
+ String path = String.format("sites/%s/settings", siteId);
+ post(path, params, null, listener, errorListener);
+ }
+
+ /**
+ * Delete a site
+ */
+ public void deleteSite(String siteId, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/delete", siteId);
+ post(path, listener, errorListener);
+ }
+
+ public void getSitePurchases(String siteId, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/purchases", siteId);
+ get(path, listener, errorListener);
+ }
+
+ public void exportContentAll(String siteId, Listener listener, ErrorListener errorListener) {
+ String path = String.format("sites/%s/exports/start", siteId);
+ post(path, listener, errorListener);
+ }
+
+ public void sendLoginEmail(Map<String, String> params, Listener listener, ErrorListener errorListener) {
+ post("auth/send-login-email", params, null, listener, errorListener);
+ }
+
+ public void isAvailable(String email, Listener listener, ErrorListener errorListener) {
+ String path = String.format("is-available/email?q=%s", email);
+ get(path, listener, errorListener);
+ }
+
+ /**
+ * Make GET request
+ */
+ public Request<JSONObject> get(String path, Listener listener, ErrorListener errorListener) {
+ return get(path, null, null, listener, errorListener);
+ }
+
+ /**
+ * Make GET request with params
+ */
+ public Request<JSONObject> get(String path, Map<String, String> params, RetryPolicy retryPolicy, Listener listener,
+ ErrorListener errorListener) {
+ // turn params into querystring
+ HashMap<String, String> paramsWithLocale = getRestLocaleParams(mContext);
+ if (params != null) {
+ paramsWithLocale.putAll(params);
+ }
+
+ String realPath = getSanitizedPath(path);
+ if (TextUtils.isEmpty(realPath)) {
+ realPath = path;
+ }
+ paramsWithLocale.putAll(getSanitizedParameters(path));
+
+ RestRequest request = mRestClient.makeRequest(Method.GET, mRestClient.getAbsoluteURL(realPath, paramsWithLocale), null,
+ listener, errorListener);
+
+ if (retryPolicy == null) {
+ retryPolicy = new DefaultRetryPolicy(REST_TIMEOUT_MS, REST_MAX_RETRIES_GET, REST_BACKOFF_MULT);
+ }
+ request.setRetryPolicy(retryPolicy);
+ AuthenticatorRequest authCheck = new AuthenticatorRequest(request, errorListener, mRestClient, mAuthenticator);
+ authCheck.send();
+ return request;
+ }
+
+ /**
+ * Make Synchronous GET request
+ *
+ * @throws TimeoutException
+ * @throws ExecutionException
+ * @throws InterruptedException
+ */
+ public JSONObject getSynchronous(String path) throws InterruptedException, ExecutionException, TimeoutException {
+ return getSynchronous(path, null, null);
+ }
+
+ /**
+ * Make Synchronous GET request with params
+ *
+ * @throws TimeoutException
+ * @throws ExecutionException
+ * @throws InterruptedException
+ */
+ public JSONObject getSynchronous(String path, Map<String, String> params, RetryPolicy retryPolicy)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ RequestFuture<JSONObject> future = RequestFuture.newFuture();
+
+ HashMap<String, String> paramsWithLocale = getRestLocaleParams(mContext);
+ if (params != null) {
+ paramsWithLocale.putAll(params);
+ }
+
+ String realPath = getSanitizedPath(path);
+ if (TextUtils.isEmpty(realPath)) {
+ realPath = path;
+ }
+ paramsWithLocale.putAll(getSanitizedParameters(path));
+
+ RestRequest request = mRestClient.makeRequest(Method.GET, mRestClient.getAbsoluteURL(realPath, paramsWithLocale), null, future, future);
+
+ if (retryPolicy == null) {
+ retryPolicy = new DefaultRetryPolicy(REST_TIMEOUT_MS, REST_MAX_RETRIES_GET, REST_BACKOFF_MULT);
+ }
+ request.setRetryPolicy(retryPolicy);
+
+ AuthenticatorRequest authCheck = new AuthenticatorRequest(request, null, mRestClient, mAuthenticator);
+ authCheck.send(); //this insert the request into the queue. //TODO: Verify that everything is OK on REST calls without a valid token
+ JSONObject response = future.get();
+ return response;
+ }
+
+ /**
+ * Make POST request
+ */
+ public void post(String path, Listener listener, ErrorListener errorListener) {
+ Map<String, String> params = null;
+ post(path, params, null, listener, errorListener);
+ }
+
+ /**
+ * Make POST request with params
+ */
+ public void post(final String path, Map<String, String> params, RetryPolicy retryPolicy, Listener listener,
+ ErrorListener errorListener) {
+ final RestRequest request = mRestClient.makeRequest(Method.POST, mRestClient.getAbsoluteURL(path, getRestLocaleParams(mContext)), params,
+ listener, errorListener);
+ if (retryPolicy == null) {
+ retryPolicy = new DefaultRetryPolicy(REST_TIMEOUT_MS, REST_MAX_RETRIES_POST,
+ REST_BACKOFF_MULT); //Do not retry on failure
+ }
+ request.setRetryPolicy(retryPolicy);
+ AuthenticatorRequest authCheck = new AuthenticatorRequest(request, errorListener, mRestClient, mAuthenticator);
+ authCheck.send();
+ }
+
+
+ /**
+ * Make a JSON POST request
+ */
+ public void post(final String path, JSONObject params, RetryPolicy retryPolicy, Listener listener,
+ ErrorListener errorListener) {
+ final JsonRestRequest request = mRestClient.makeRequest(mRestClient.getAbsoluteURL(path, getRestLocaleParams(mContext)), params,
+ listener, errorListener);
+ if (retryPolicy == null) {
+ retryPolicy = new DefaultRetryPolicy(REST_TIMEOUT_MS, REST_MAX_RETRIES_POST,
+ REST_BACKOFF_MULT); //Do not retry on failure
+ }
+ request.setRetryPolicy(retryPolicy);
+ AuthenticatorRequest authCheck = new AuthenticatorRequest(request, errorListener, mRestClient, mAuthenticator);
+ authCheck.send();
+ }
+
+ /**
+ * Takes a URL and returns the path within, or an empty string (not null)
+ */
+ public static String getSanitizedPath(String unsanitizedPath){
+ if (unsanitizedPath != null) {
+ int qmarkPos = unsanitizedPath.indexOf('?');
+ if (qmarkPos > -1) { //strip any querystring params off this to obtain the path
+ return unsanitizedPath.substring(0, qmarkPos+1);
+ } else {
+ // return the string as is, consider the whole string as the path
+ return unsanitizedPath;
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Takes a URL with query strings and returns a Map of query string values.
+ */
+ public static HashMap<String, String> getSanitizedParameters(String unsanitizedPath){
+ HashMap<String, String> queryParams = new HashMap<>();
+
+ Uri uri = Uri.parse(unsanitizedPath);
+
+ if (uri.getQueryParameterNames() != null ) {
+ Iterator iter = uri.getQueryParameterNames().iterator();
+ while (iter.hasNext()) {
+ String name = (String)iter.next();
+ String value = uri.getQueryParameter(name);
+ queryParams.put(name, value);
+ }
+ }
+
+ return queryParams;
+ }
+
+ /**
+ * Returns locale parameter used in REST calls which require the response to be localized
+ */
+ public static HashMap<String, String> getRestLocaleParams(Context context) {
+ HashMap<String, String> params = new HashMap<>();
+ String deviceLanguageCode = LanguageUtils.getCurrentDeviceLanguageCode(context);
+ if (!TextUtils.isEmpty(deviceLanguageCode)) {
+ //patch locale if it's any of the deprecated codes as can be read in Locale.java source code:
+ deviceLanguageCode = LanguageUtils.patchDeviceLanguageCode(deviceLanguageCode);
+ params.put("locale", deviceLanguageCode);
+ }
+ return params;
+ }
+
+}