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
This commit is contained in:
Dave Borowitz
2016-05-02 16:56:36 -04:00
parent a101030aff
commit dba0801601
4 changed files with 70 additions and 58 deletions

View File

@@ -122,46 +122,8 @@ public final class Account {
* 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;
}
}

View File

@@ -174,6 +174,49 @@ public class RefNames {
.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() {
}
}

View File

@@ -45,24 +45,7 @@ public class AccountTest {
@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) {

View File

@@ -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 @@ public class RefNamesTest {
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();
}
}