Move method for parsing ref parts (CD/ABCD/...) to RefNames

This is currently only used from Account but will shortly be used from
Change. The commonality is parsing to an Integer, which then needs to
be wrapped in a specific type.

Change-Id: I1dda21ed25ccb92c89f265794e36738e7d99ba9d
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Account.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Account.java
index 77b0137..4d20f24 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Account.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/Account.java
@@ -122,46 +122,8 @@
      *              We assume that the caller has trimmed any prefix.
      */
     public static Id fromRefPart(String name) {
-      if (name == null) {
-        return null;
-      }
-
-      String[] parts = name.split("/");
-      int n = parts.length;
-      if (n < 2) {
-        return null;
-      }
-
-      // Last 2 digits.
-      int le;
-      for (le = 0; le < parts[0].length(); le++) {
-        if (!Character.isDigit(parts[0].charAt(le))) {
-          return null;
-        }
-      }
-      if (le != 2) {
-        return null;
-      }
-
-      // Full ID.
-      int ie;
-      for (ie = 0; ie < parts[1].length(); ie++) {
-        if (!Character.isDigit(parts[1].charAt(ie))) {
-          if (ie == 0) {
-            return null;
-          } else {
-            break;
-          }
-        }
-      }
-
-      int shard = Integer.parseInt(parts[0]);
-      int id = Integer.parseInt(parts[1].substring(0, ie));
-
-      if (id % 100 != shard) {
-        return null;
-      }
-      return new Account.Id(id);
+      Integer id = RefNames.parseShardedRefPart(name);
+      return id != null ? new Account.Id(id) : null;
     }
   }
 
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java
index 1486c93..0257376 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/RefNames.java
@@ -174,6 +174,49 @@
       .toString();
   }
 
+  static Integer parseShardedRefPart(String name) {
+    if (name == null) {
+      return null;
+    }
+
+    String[] parts = name.split("/");
+    int n = parts.length;
+    if (n < 2) {
+      return null;
+    }
+
+    // Last 2 digits.
+    int le;
+    for (le = 0; le < parts[0].length(); le++) {
+      if (!Character.isDigit(parts[0].charAt(le))) {
+        return null;
+      }
+    }
+    if (le != 2) {
+      return null;
+    }
+
+    // Full ID.
+    int ie;
+    for (ie = 0; ie < parts[1].length(); ie++) {
+      if (!Character.isDigit(parts[1].charAt(ie))) {
+        if (ie == 0) {
+          return null;
+        } else {
+          break;
+        }
+      }
+    }
+
+    int shard = Integer.parseInt(parts[0]);
+    int id = Integer.parseInt(parts[1].substring(0, ie));
+
+    if (id % 100 != shard) {
+      return null;
+    }
+    return id;
+  }
+
   private RefNames() {
   }
 }
diff --git a/gerrit-reviewdb/src/test/java/com/google/gerrit/reviewdb/client/AccountTest.java b/gerrit-reviewdb/src/test/java/com/google/gerrit/reviewdb/client/AccountTest.java
index 77784d4..551cb0f 100644
--- a/gerrit-reviewdb/src/test/java/com/google/gerrit/reviewdb/client/AccountTest.java
+++ b/gerrit-reviewdb/src/test/java/com/google/gerrit/reviewdb/client/AccountTest.java
@@ -45,24 +45,7 @@
   @Test
   public void parseRefNameParts() {
     assertThat(fromRefPart("01/1")).isEqualTo(id(1));
-    assertThat(fromRefPart("01/1-drafts")).isEqualTo(id(1));
-    assertThat(fromRefPart("01/1-drafts/2")).isEqualTo(id(1));
-
-    assertThat(fromRefPart(null)).isNull();
-    assertThat(fromRefPart("")).isNull();
-
-    // This method assumes that the common prefix "refs/users/" will be removed.
-    assertThat(fromRefPart("refs/users/01/1")).isNull();
-
-    // Invalid characters.
-    assertThat(fromRefPart("01a/1")).isNull();
-    assertThat(fromRefPart("01/a1")).isNull();
-
-    // Mismatched shard.
-    assertThat(fromRefPart("01/23")).isNull();
-
-    // Shard too short.
-    assertThat(fromRefPart("1/1")).isNull();
+    assertThat(fromRefPart("ab/cd")).isNull();
   }
 
   private Account.Id id(int n) {
diff --git a/gerrit-reviewdb/src/test/java/com/google/gerrit/reviewdb/client/RefNamesTest.java b/gerrit-reviewdb/src/test/java/com/google/gerrit/reviewdb/client/RefNamesTest.java
index 6797ffb..875b6a2 100644
--- a/gerrit-reviewdb/src/test/java/com/google/gerrit/reviewdb/client/RefNamesTest.java
+++ b/gerrit-reviewdb/src/test/java/com/google/gerrit/reviewdb/client/RefNamesTest.java
@@ -15,6 +15,7 @@
 package com.google.gerrit.reviewdb.client;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.reviewdb.client.RefNames.parseShardedRefPart;
 
 import org.junit.Test;
 
@@ -65,4 +66,27 @@
     assertThat(RefNames.refsEdit(accountId, changeId, psId))
       .isEqualTo("refs/users/23/1011123/edit-67473/42");
   }
+
+  @Test
+  public void testParseShardedRefsPart() throws Exception {
+    assertThat(parseShardedRefPart("01/1")).isEqualTo(1);
+    assertThat(parseShardedRefPart("01/1-drafts")).isEqualTo(1);
+    assertThat(parseShardedRefPart("01/1-drafts/2")).isEqualTo(1);
+
+    assertThat(parseShardedRefPart(null)).isNull();
+    assertThat(parseShardedRefPart("")).isNull();
+
+    // Prefix not stripped.
+    assertThat(parseShardedRefPart("refs/users/01/1")).isNull();
+
+    // Invalid characters.
+    assertThat(parseShardedRefPart("01a/1")).isNull();
+    assertThat(parseShardedRefPart("01/a1")).isNull();
+
+    // Mismatched shard.
+    assertThat(parseShardedRefPart("01/23")).isNull();
+
+    // Shard too short.
+    assertThat(parseShardedRefPart("1/1")).isNull();
+  }
 }