Refactor: Extract code to parse approvals into a class

This way the code gets reusable.

Change-Id: I7de37045176e656aa928298ed3f84428e4ab2772
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/app/src/main/java/com/google/reviewit/DetailedChangeFragment.java b/app/src/main/java/com/google/reviewit/DetailedChangeFragment.java
index b1f8a36..8e0b3a3 100644
--- a/app/src/main/java/com/google/reviewit/DetailedChangeFragment.java
+++ b/app/src/main/java/com/google/reviewit/DetailedChangeFragment.java
@@ -89,8 +89,8 @@
       ((ChangeBox) v(R.id.changeBox)).display(getApp(), change);
       (new Linkifier(getApp())).linkifyCommitMessage(tv(R.id.commitMessage));
       displayChangeUrl(change);
-      ((ApprovalsView) v(R.id.approvals)).displayApprovals(getApp(),
-          change.info, this);
+      ((ApprovalsView) v(R.id.approvals)).displayApprovals(
+          getApp(), change, this);
       ((FileBox)v(R.id.fileBox)).display(this, change);
       // TODO show further change info, e.g. summary comments, hashtags,
       // related changes
diff --git a/app/src/main/java/com/google/reviewit/app/ApprovalData.java b/app/src/main/java/com/google/reviewit/app/ApprovalData.java
new file mode 100644
index 0000000..63316b8
--- /dev/null
+++ b/app/src/main/java/com/google/reviewit/app/ApprovalData.java
@@ -0,0 +1,86 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.reviewit.app;
+
+import com.google.gerrit.extensions.client.ReviewerState;
+import com.google.gerrit.extensions.common.AccountInfo;
+import com.google.gerrit.extensions.common.ApprovalInfo;
+import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.LabelInfo;
+import com.google.reviewit.util.FormatUtil;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+public class ApprovalData {
+  public final Set<AccountInfo> reviewers;
+  public final Map<String, LabelInfo> labels;
+  public final TreeMap<String, Map<Integer, ApprovalInfo>> approvalsByLabel;
+
+  public ApprovalData(ChangeInfo change) {
+    reviewers = new TreeSet<>(new Comparator<AccountInfo>() {
+      @Override
+      public int compare(AccountInfo account1, AccountInfo account2) {
+        return FormatUtil.format(account1).compareTo(
+            FormatUtil.format(account2));
+      }
+    });
+    if (change.reviewers != null
+        && change.reviewers.containsKey(ReviewerState.REVIEWER)) {
+      reviewers.addAll(change.reviewers.get(ReviewerState.REVIEWER));
+    }
+    labels = new TreeMap<>();
+    approvalsByLabel = new TreeMap<>();
+    for (Map.Entry<String, LabelInfo> label : change.labels.entrySet()) {
+      Map<Integer, ApprovalInfo> approvalsByAccount = new HashMap<>();
+      labels.put(label.getKey(), label.getValue());
+      approvalsByLabel.put(label.getKey(), approvalsByAccount);
+      List<ApprovalInfo> all = change.labels.get(label.getKey()).all;
+      if (all != null) {
+        for (ApprovalInfo approval : all) {
+          reviewers.add(approval);
+          approvalsByAccount.put(approval._accountId, approval);
+        }
+      }
+    }
+  }
+
+  public boolean isMax(LabelInfo label, int value) {
+    Integer max = null;
+    for (String rangeValue : label.values.keySet()) {
+      Integer v = Integer.parseInt(rangeValue.trim());
+      if (max == null || v.intValue() > max.intValue()) {
+        max = v;
+      }
+    }
+    return max != null && max.equals(Integer.valueOf(value));
+  }
+
+  public boolean isMin(LabelInfo label, int value) {
+    Integer min = null;
+    for (String rangeValue : label.values.keySet()) {
+      Integer v = Integer.parseInt(rangeValue.trim());
+      if (min == null || v.intValue() < min.intValue()) {
+        min = v;
+      }
+    }
+    return min != null && min.equals(Integer.valueOf(value));
+  }
+}
diff --git a/app/src/main/java/com/google/reviewit/app/Change.java b/app/src/main/java/com/google/reviewit/app/Change.java
index e2009d2..f926b6f 100644
--- a/app/src/main/java/com/google/reviewit/app/Change.java
+++ b/app/src/main/java/com/google/reviewit/app/Change.java
@@ -47,6 +47,7 @@
   public ChangeInfo info;
   private Map<String, DiffInfo> diffs = new HashMap<>();
   private Integer inlineCommentCount;
+  private ApprovalData approvalData;
 
   public Change(GerritApi api, ChangeInfo info) {
     this.api = api;
@@ -217,4 +218,11 @@
   public String getUrl(String serverUrl) {
     return FormatUtil.ensureSlash(serverUrl) + "#/c/" + info._number;
   }
+
+  public ApprovalData getApprovalData() {
+    if (approvalData == null) {
+      approvalData = new ApprovalData(info);
+    }
+    return approvalData;
+  }
 }
diff --git a/app/src/main/java/com/google/reviewit/widget/ApprovalsView.java b/app/src/main/java/com/google/reviewit/widget/ApprovalsView.java
index 47094f9..8dd15ad 100644
--- a/app/src/main/java/com/google/reviewit/widget/ApprovalsView.java
+++ b/app/src/main/java/com/google/reviewit/widget/ApprovalsView.java
@@ -25,26 +25,20 @@
 import android.widget.TableRow;
 import android.widget.TextView;
 
-import com.google.gerrit.extensions.client.ReviewerState;
 import com.google.gerrit.extensions.common.AccountInfo;
 import com.google.gerrit.extensions.common.ApprovalInfo;
-import com.google.gerrit.extensions.common.ChangeInfo;
 import com.google.gerrit.extensions.common.LabelInfo;
 import com.google.reviewit.AddReviewerFragment;
 import com.google.reviewit.AvatarTask;
 import com.google.reviewit.BaseFragment;
 import com.google.reviewit.R;
+import com.google.reviewit.app.ApprovalData;
+import com.google.reviewit.app.Change;
 import com.google.reviewit.app.ReviewItApp;
 import com.google.reviewit.util.FormatUtil;
 import com.google.reviewit.util.WidgetUtil;
 
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
 
 import static com.google.reviewit.util.LayoutUtil.matchAndWrapTableLayout;
 import static com.google.reviewit.util.LayoutUtil.matchAndWrapTableRowLayout;
@@ -69,7 +63,7 @@
   }
 
   public void displayApprovals(
-      ReviewItApp app, ChangeInfo change, final BaseFragment origin) {
+      ReviewItApp app, Change change, final BaseFragment origin) {
     TableRow headerRow = new TableRow(getContext());
     headerRow.setLayoutParams(matchAndWrapTableRowLayout());
     LinearLayout l = new LinearLayout(getContext());
@@ -101,34 +95,9 @@
     headerRow.addView(l);
     addView(headerRow, matchAndWrapTableLayout());
 
-    Set<AccountInfo> reviewers = new TreeSet<>(new Comparator<AccountInfo>() {
-      @Override
-      public int compare(AccountInfo account1, AccountInfo account2) {
-        return FormatUtil.format(account1).compareTo(
-            FormatUtil.format(account2));
-      }
-    });
-    if (change.reviewers != null
-        && change.reviewers.containsKey(ReviewerState.REVIEWER)) {
-      reviewers.addAll(change.reviewers.get(ReviewerState.REVIEWER));
-    }
-    Map<String, LabelInfo> labels = new TreeMap<>();
-    TreeMap<String, Map<Integer, ApprovalInfo>> approvalsByLabel =
-        new TreeMap<>();
-    for (Map.Entry<String, LabelInfo> label : change.labels.entrySet()) {
-      Map<Integer, ApprovalInfo> approvalsByAccount = new HashMap<>();
-      labels.put(label.getKey(), label.getValue());
-      approvalsByLabel.put(label.getKey(), approvalsByAccount);
-      List<ApprovalInfo> all = change.labels.get(label.getKey()).all;
-      if (all != null) {
-        for (ApprovalInfo approval : all) {
-          reviewers.add(approval);
-          approvalsByAccount.put(approval._accountId, approval);
-        }
-      }
-    }
 
-    for (String labelName : labels.keySet()) {
+    ApprovalData approvalData = change.getApprovalData();
+    for (String labelName : approvalData.labels.keySet()) {
       TextView labelNameText = widgetUtil.createTextView(
           FormatUtil.formatLabelName(labelName), 16);
       labelNameText.setPadding(
@@ -136,8 +105,8 @@
       headerRow.addView(center(labelNameText));
     }
 
-    for (AccountInfo account : reviewers) {
-      addApprovalRow(app, account, labels, approvalsByLabel);
+    for (AccountInfo account : approvalData.reviewers) {
+      addApprovalRow(app, account, approvalData);
     }
   }
 
@@ -146,8 +115,7 @@
   }
 
   private void addApprovalRow(
-      ReviewItApp app, AccountInfo account, Map<String, LabelInfo> labels,
-      TreeMap<String, Map<Integer, ApprovalInfo>> approvalsByLabel) {
+      ReviewItApp app, AccountInfo account, ApprovalData approvalData) {
     TableRow tr = new TableRow(getContext());
     tr.setLayoutParams(matchAndWrapTableRowLayout());
     int textSizeSp = 14;
@@ -159,9 +127,9 @@
             FormatUtil.format(account), textSizeSp), 4), 5));
 
     for (Map.Entry<String, Map<Integer, ApprovalInfo>> e
-        : approvalsByLabel.entrySet()) {
+        : approvalData.approvalsByLabel.entrySet()) {
       String labelName = e.getKey();
-      LabelInfo label = labels.get(labelName);
+      LabelInfo label = approvalData.labels.get(labelName);
 
       if (label.approved != null
           && label.approved._accountId.equals(account._accountId)) {
@@ -172,9 +140,9 @@
       } else {
         ApprovalInfo approval = e.getValue().get(account._accountId);
         if (approval != null && approval.value != null) {
-          if (isMax(label, approval.value)) {
+          if (approvalData.isMax(label, approval.value)) {
             tr.addView(createPositiveVoteIcon());
-          } else if (isMin(label, approval.value)) {
+          } else if (approvalData.isMin(label, approval.value)) {
             tr.addView(createNegativeVoteIcon());
           } else {
             TextView text = widgetUtil.createTextView(
@@ -197,28 +165,6 @@
     addView(tr, matchAndWrapTableLayout());
   }
 
-  private boolean isMax(LabelInfo label, int value) {
-    Integer max = null;
-    for (String rangeValue : label.values.keySet()) {
-      Integer v = Integer.parseInt(rangeValue.trim());
-      if (max == null || v.intValue() > max.intValue()) {
-        max = v;
-      }
-    }
-    return max != null && max.equals(Integer.valueOf(value));
-  }
-
-  private boolean isMin(LabelInfo label, int value) {
-    Integer min = null;
-    for (String rangeValue : label.values.keySet()) {
-      Integer v = Integer.parseInt(rangeValue.trim());
-      if (min == null || v.intValue() < min.intValue()) {
-        min = v;
-      }
-    }
-    return min != null && min.equals(Integer.valueOf(value));
-  }
-
   private ImageView createAvatar(ReviewItApp app, AccountInfo account) {
     ImageView avatar = createImageView();
     TableRow.LayoutParams layoutParams =
diff --git a/app/src/main/java/com/google/reviewit/widget/PostReviewView.java b/app/src/main/java/com/google/reviewit/widget/PostReviewView.java
index 1e657a1..47e7aae 100644
--- a/app/src/main/java/com/google/reviewit/widget/PostReviewView.java
+++ b/app/src/main/java/com/google/reviewit/widget/PostReviewView.java
@@ -87,7 +87,7 @@
     ApprovalsView approvalsView =
         ((ApprovalsView) findViewById(R.id.approvals));
     if (approvalsView != null) {
-      approvalsView.displayApprovals(app, change.info, origin);
+      approvalsView.displayApprovals(app, change, origin);
     }
   }