Mholloway has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/333380 )

Change subject: Hygiene: Clean up some editing-related classes
......................................................................

Hygiene: Clean up some editing-related classes

* Reorganizes the result handling logic in EditClient for better
  readability

* Brings EditAbuseFilterResult up to present-day standards and updates
  the constructor to remove the need to remarshal the response to pass in

* Moves the two-second delay out of the data client before calling
  cb.success, and out into the caller.  Besides being cleaner in general
  this has the added benefit of removing unnecessary delays when dealing
  with results other than edit success (abuse filter, spam blacklist,
  captcha).

Change-Id: I31e5225d5d7280fa5dd0bd67c4231e16450b8918
---
M app/src/main/java/org/wikipedia/edit/Edit.java
M app/src/main/java/org/wikipedia/edit/EditAbuseFilterResult.java
M app/src/main/java/org/wikipedia/edit/EditClient.java
M app/src/main/java/org/wikipedia/edit/EditSectionActivity.java
4 files changed, 104 insertions(+), 77 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia 
refs/changes/80/333380/1

diff --git a/app/src/main/java/org/wikipedia/edit/Edit.java 
b/app/src/main/java/org/wikipedia/edit/Edit.java
index f6079de..7cbff62 100644
--- a/app/src/main/java/org/wikipedia/edit/Edit.java
+++ b/app/src/main/java/org/wikipedia/edit/Edit.java
@@ -20,6 +20,8 @@
         @SuppressWarnings("unused") private int newrevid;
         @SuppressWarnings("unused") @Nullable private Captcha captcha;
         @SuppressWarnings("unused") @Nullable private String code;
+        @SuppressWarnings("unused") @Nullable private String info;
+        @SuppressWarnings("unused") @Nullable private String warning;
         @SuppressWarnings("unused") @Nullable private String spamblacklist;
 
         @Nullable String status() {
@@ -34,7 +36,7 @@
             return captcha == null ? null : captcha.id();
         }
 
-        boolean hasErrorCode() {
+        boolean hasEditErrorCode() {
             return code != null;
         }
 
@@ -42,6 +44,18 @@
             return captcha != null;
         }
 
+        @Nullable String code() {
+            return code;
+        }
+
+        @Nullable String info() {
+            return info;
+        }
+
+        @Nullable String warning() {
+            return warning;
+        }
+
         @Nullable String spamblacklist() {
             return spamblacklist;
         }
diff --git a/app/src/main/java/org/wikipedia/edit/EditAbuseFilterResult.java 
b/app/src/main/java/org/wikipedia/edit/EditAbuseFilterResult.java
index e3cb395..843c795 100644
--- a/app/src/main/java/org/wikipedia/edit/EditAbuseFilterResult.java
+++ b/app/src/main/java/org/wikipedia/edit/EditAbuseFilterResult.java
@@ -2,45 +2,43 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.annotation.Nullable;
 
-import org.json.JSONObject;
+class EditAbuseFilterResult extends EditResult {
+    static final int TYPE_WARNING = 1;
+    static final int TYPE_ERROR = 2;
 
-public class EditAbuseFilterResult extends EditResult {
-    public static final int TYPE_WARNING = 1;
-    public static final int TYPE_ERROR = 2;
+    @Nullable private final String code;
+    @Nullable private final String info;
+    @Nullable private final String warning;
 
-    private final String code;
-    private final String info;
-    private final String warning;
-
-    public EditAbuseFilterResult(JSONObject result) {
+    EditAbuseFilterResult(@Nullable String code, @Nullable String info, 
@Nullable String warning) {
         super("Failure");
-        this.code = result.optString("code");
-        this.info = result.optString("info");
-        this.warning = result.optString("warning");
+        this.code = code;
+        this.info = info;
+        this.warning = warning;
     }
 
-    protected EditAbuseFilterResult(Parcel in) {
+    private EditAbuseFilterResult(Parcel in) {
         super(in);
         code = in.readString();
         info = in.readString();
         warning = in.readString();
     }
 
-    public String getCode() {
+    @Nullable public String getCode() {
         return code;
     }
 
-    public String getInfo() {
+    @Nullable public String getInfo() {
         return info;
     }
 
-    public String getWarning() {
+    @Nullable public String getWarning() {
         return warning;
     }
 
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
+    @Override public void writeToParcel(Parcel dest, int flags) {
         super.writeToParcel(dest, flags);
         dest.writeString(code);
         dest.writeString(info);
@@ -48,11 +46,11 @@
     }
 
     public int getType() {
-        if (code.startsWith("abusefilter-warning")) {
+        if (code != null && code.startsWith("abusefilter-warning")) {
             return TYPE_WARNING;
-        } else if (code.startsWith("abusefilter-disallowed")) {
+        } else if (code != null && code.startsWith("abusefilter-disallowed")) {
             return TYPE_ERROR;
-        } else if (info.startsWith("Hit AbuseFilter")) {
+        } else if (info != null && info.startsWith("Hit AbuseFilter")) {
             // This case is here because, unfortunately, an admin can create 
an abuse filter which
             // emits an arbitrary error code over the API.
             // TODO: More properly handle the case where the AbuseFilter 
throws an arbitrary error.
diff --git a/app/src/main/java/org/wikipedia/edit/EditClient.java 
b/app/src/main/java/org/wikipedia/edit/EditClient.java
index e2343eb..bad2fe4 100644
--- a/app/src/main/java/org/wikipedia/edit/EditClient.java
+++ b/app/src/main/java/org/wikipedia/edit/EditClient.java
@@ -4,15 +4,14 @@
 import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
 
-import org.json.JSONException;
-import org.json.JSONObject;
 import org.wikipedia.captcha.CaptchaResult;
 import org.wikipedia.dataclient.WikiSite;
+import org.wikipedia.dataclient.mwapi.MwApiException;
 import org.wikipedia.dataclient.retrofit.MwCachedService;
-import org.wikipedia.json.GsonMarshaller;
+import org.wikipedia.dataclient.retrofit.RetrofitException;
 import org.wikipedia.page.PageTitle;
 
-import java.util.concurrent.TimeUnit;
+import java.io.IOException;
 
 import retrofit2.Call;
 import retrofit2.Response;
@@ -21,59 +20,45 @@
 import retrofit2.http.POST;
 
 class EditClient {
-    @NonNull private final MwCachedService<Service> cachedService
-            = new MwCachedService<>(Service.class);
+    @NonNull private final MwCachedService<Service> cachedService = new 
MwCachedService<>(Service.class);
 
-    @SuppressWarnings("checkstyle:parameternumber")
-    public Call<Edit> request(@NonNull WikiSite wiki, @NonNull PageTitle 
title, int section,
-                        @NonNull String text, @NonNull String token, @NonNull 
String summary,
-                        boolean loggedIn, @Nullable String captchaId, 
@Nullable String captchaWord,
-                        @NonNull Callback cb) {
-        Service service = cachedService.service(wiki);
-        return request(service, title, section, text, token, summary, 
loggedIn, captchaId, captchaWord, cb);
+    public interface Callback {
+        void success(@NonNull Call<Edit> call, @NonNull EditResult result);
+        void failure(@NonNull Call<Edit> call, @NonNull Throwable caught);
     }
 
     @SuppressWarnings("checkstyle:parameternumber")
-    @VisibleForTesting Call<Edit> request(@NonNull Service service, @NonNull 
PageTitle title, int section,
+    public Call<Edit> request(@NonNull WikiSite wiki, @NonNull PageTitle 
title, int section,
+                              @NonNull String text, @NonNull String token, 
@NonNull String summary,
+                              boolean loggedIn, @Nullable String captchaId, 
@Nullable String captchaWord,
+                              @NonNull Callback cb) {
+        return request(cachedService.service(wiki), title, section, text, 
token, summary, loggedIn,
+                captchaId, captchaWord, cb);
+    }
+
+    @VisibleForTesting @SuppressWarnings("checkstyle:parameternumber")
+    Call<Edit> request(@NonNull Service service, @NonNull PageTitle title, int 
section,
                        @NonNull String text, @NonNull String token, @NonNull 
String summary,
                        boolean loggedIn, @Nullable String captchaId, @Nullable 
String captchaWord,
                        @NonNull final Callback cb) {
-        Call<Edit> call = service.edit(title.getPrefixedText(), section, text,
-                token, summary, loggedIn ? "user" : null, captchaId, 
captchaWord);
+        Call<Edit> call = service.edit(title.getPrefixedText(), section, text, 
token, summary,
+                loggedIn ? "user" : null, captchaId, captchaWord);
         call.enqueue(new retrofit2.Callback<Edit>() {
             @Override
             public void onResponse(Call<Edit> call, Response<Edit> response) {
-                if (response.isSuccessful() && 
response.body().hasEditResult()) {
-                    Edit.Result result = response.body().edit();
-                    if ("Success".equals(result.status())) {
-                        try {
-                            // TODO: get edit revision and request that 
revision
-                            Thread.sleep(TimeUnit.SECONDS.toMillis(2));
-                            cb.success(call, new 
EditSuccessResult(result.newRevId()));
-                        } catch (InterruptedException e) {
-                            cb.failure(call, e);
-                        }
-                    } else if (result.hasErrorCode()) {
-                        try {
-                            JSONObject json = new 
JSONObject(GsonMarshaller.marshal(result));
-                            cb.success(call, new EditAbuseFilterResult(json));
-                        } catch (JSONException e) {
-                            cb.failure(call, e);
-                        }
-                    } else if (result.hasSpamBlacklistResponse()) {
-                        cb.success(call, new 
EditSpamBlacklistResult(result.spamblacklist()));
-                    } else if (result.hasCaptchaResponse()) {
-                        cb.success(call, new 
CaptchaResult(result.captchaId()));
+                if (response.isSuccessful()) {
+                    if (response.body().hasEditResult()) {
+                        handleEditResult(response.body().edit(), call, cb);
+                    } else if (response.body().hasError()) {
+                        RuntimeException e = isLoginFailure(response)
+                                ? new UserNotLoggedInException()
+                                : new 
MwApiException(response.body().getError());
+                        cb.failure(call, e);
                     } else {
-                        cb.failure(call, new RuntimeException("Received 
unrecognized edit response"));
+                        cb.failure(call, new IOException("An unknown error 
occurred."));
                     }
-                } else if ("assertuserfailed".equals(response.body().code())) {
-                    cb.failure(call, new UserNotLoggedInException());
-                } else if (response.body().info() != null) {
-                    String info = response.body().info();
-                    cb.failure(call, new RuntimeException(info));
                 } else {
-                    cb.failure(call, new RuntimeException("Received 
unrecognized edit response"));
+                    cb.failure(call, RetrofitException.httpError(response, 
cachedService.retrofit()));
                 }
             }
 
@@ -85,9 +70,28 @@
         return call;
     }
 
-    @VisibleForTesting interface Callback {
-        void success(@NonNull Call<Edit> call, @NonNull EditResult result);
-        void failure(@NonNull Call<Edit> call, @NonNull Throwable caught);
+    private void handleEditResult(@NonNull Edit.Result result, @NonNull 
Call<Edit> call,
+                                  @NonNull Callback cb) {
+        if (isEditSuccessResult(result)) {
+            // TODO: get edit revision and request that revision
+            cb.success(call, new EditSuccessResult(result.newRevId()));
+        } else if (result.hasEditErrorCode()) {
+            cb.success(call, new EditAbuseFilterResult(result.code(), 
result.info(), result.warning()));
+        } else if (result.hasSpamBlacklistResponse()) {
+            cb.success(call, new 
EditSpamBlacklistResult(result.spamblacklist()));
+        } else if (result.hasCaptchaResponse()) {
+            cb.success(call, new CaptchaResult(result.captchaId()));
+        } else {
+            cb.failure(call, new IOException("Received unrecognized edit 
response"));
+        }
+    }
+
+    private boolean isEditSuccessResult(@NonNull Edit.Result result) {
+        return "Success".equals(result.status());
+    }
+
+    private boolean isLoginFailure(@NonNull Response<Edit> response) {
+        return "assertuserfailed".equals(response.body().code());
     }
 
     @VisibleForTesting interface Service {
diff --git a/app/src/main/java/org/wikipedia/edit/EditSectionActivity.java 
b/app/src/main/java/org/wikipedia/edit/EditSectionActivity.java
index 1f3d767..40101e6 100644
--- a/app/src/main/java/org/wikipedia/edit/EditSectionActivity.java
+++ b/app/src/main/java/org/wikipedia/edit/EditSectionActivity.java
@@ -6,6 +6,7 @@
 import android.graphics.Typeface;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.v4.content.ContextCompat;
@@ -54,6 +55,8 @@
 import org.wikipedia.util.StringUtil;
 import org.wikipedia.util.log.L;
 import org.wikipedia.views.ViewAnimations;
+
+import java.util.concurrent.TimeUnit;
 
 import retrofit2.Call;
 
@@ -108,6 +111,19 @@
     private EditFunnel funnel;
 
     private ProgressDialog progressDialog;
+
+    private Runnable successRunnable = new Runnable() {
+        @Override public void run() {
+            progressDialog.dismiss();
+
+            //Build intent that includes the section we were editing, so we 
can scroll to it later
+            Intent data = new Intent();
+            data.putExtra(EXTRA_SECTION_ID, sectionID);
+            setResult(EditHandler.RESULT_REFRESH_PAGE, data);
+            hideSoftKeyboard(EditSectionActivity.this);
+            finish();
+        }
+    };
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -300,14 +316,9 @@
                                 }
                                 if (result instanceof EditSuccessResult) {
                                     funnel.logSaved(((EditSuccessResult) 
result).getRevID());
-                                    progressDialog.dismiss();
-
-                                    //Build intent that includes the section 
we were editing, so we can scroll to it later
-                                    Intent data = new Intent();
-                                    data.putExtra(EXTRA_SECTION_ID, sectionID);
-                                    setResult(EditHandler.RESULT_REFRESH_PAGE, 
data);
-                                    hideSoftKeyboard(EditSectionActivity.this);
-                                    finish();
+                                    // TODO: remove this artificial delay and 
use the new revision
+                                    // ID returned to request the updated 
version of the page
+                                    new Handler().postDelayed(successRunnable, 
TimeUnit.SECONDS.toMillis(2));
                                 } else if (result instanceof CaptchaResult) {
                                     if (captchaHandler.isActive()) {
                                         // Captcha entry failed!

-- 
To view, visit https://gerrit.wikimedia.org/r/333380
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I31e5225d5d7280fa5dd0bd67c4231e16450b8918
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mholloway <mhollo...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to