diff options
author | Chris Warrington <cmw@google.com> | 2016-10-18 12:29:21 +0100 |
---|---|---|
committer | Chris Warrington <cmw@google.com> | 2016-10-18 12:34:18 +0100 |
commit | e3780081075c01aa1dff6d1f373cb43192b33e68 (patch) | |
tree | fb734615933a39f3d009210dc0d1457160479b35 /libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientUtils.java | |
parent | 7e05eb7e57827eddc885570bc00aed8a50320dbf (diff) | |
parent | 025b8b226c8d8edba2b309ca878572f40512eca7 (diff) | |
download | gradle-perf-android-medium-e3780081075c01aa1dff6d1f373cb43192b33e68.tar.gz |
Merge remote-tracking branch 'origin/upstream-master' into masterHEADstudio-3.4.0studio-3.2.1studio-3.1.2studio-3.0studio-2.3gradle_3.4.0gradle_3.1.2gradle_3.0.0gradle_2.3.0studio-master-devmirror-goog-studio-master-devmastermain
Change-Id: I63f5e16d09297c48432192761b840310935eb903
Diffstat (limited to 'libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientUtils.java')
-rw-r--r-- | libs/networking/WordPressNetworking/src/main/java/org/wordpress/android/networking/RestClientUtils.java | 475 |
1 files changed, 475 insertions, 0 deletions
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; + } + +} |