Consolidate parsing and formatting for label votes

We currently support two styles of parsing, Label-Value and
Label=Value. Consolidate these into a single LabelVote class.
(Unfortunately for backwards-compatibility reasons we can't just
eliminate Label=Value in ReviewCommand.)

Change-Id: I9e5255b184d786226e6b11fe059001608c00673d
This commit is contained in:
Dave Borowitz
2013-12-10 18:26:52 -08:00
parent d6bbc3fcfb
commit 57ecf24c06
6 changed files with 244 additions and 42 deletions

View File

@@ -49,6 +49,7 @@ import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountsCollection;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.util.LabelVote;
import com.google.gerrit.server.util.TimeUtil;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -387,7 +388,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
// User requested delete of this label.
if (c != null) {
if (c.getValue() != 0) {
labelDelta.add("-" + normName);
addLabelDelta(normName, (short) 0);
}
del.add(c);
}
@@ -395,7 +396,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
c.setValue(ent.getValue());
c.setGranted(timestamp);
upd.add(c);
labelDelta.add(format(normName, c.getValue()));
addLabelDelta(normName, c.getValue());
categories.put(normName, c.getValue());
} else if (c != null && c.getValue() == ent.getValue()) {
current.put(normName, c);
@@ -407,7 +408,7 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
ent.getValue(), TimeUtil.nowTs());
c.setGranted(timestamp);
ins.add(c);
labelDelta.add(format(normName, c.getValue()));
addLabelDelta(normName, c.getValue());
categories.put(normName, c.getValue());
}
}
@@ -467,14 +468,8 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
return current;
}
private static String format(String name, short value) {
StringBuilder sb = new StringBuilder(name.length() + 2);
sb.append(name);
if (value >= 0) {
sb.append('+');
}
sb.append(value);
return sb.toString();
private void addLabelDelta(String name, short value) {
labelDelta.add(new LabelVote(name, value).format());
}
private boolean insertMessage(RevisionResource rsrc, String msg)

View File

@@ -23,6 +23,7 @@ import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.query.OrPredicate;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.util.LabelVote;
import com.google.inject.Provider;
import java.util.List;
@@ -75,25 +76,39 @@ public class LabelPredicate extends OrPredicate<ChangeData> {
ProjectCache projectCache, ChangeControl.GenericFactory ccFactory,
IdentifiedUser.GenericFactory userFactory, Provider<ReviewDb> dbProvider,
String value, Set<Account.Id> accounts, AccountGroup.UUID group) {
String label;
Test test;
int expVal;
Matcher m1 = Pattern.compile("(=|>=|<=)([+-]?\\d+)$").matcher(value);
Matcher m2 = Pattern.compile("([+-]\\d+)$").matcher(value);
if (m1.find()) {
label = value.substring(0, m1.start());
test = Test.op(m1.group(1));
expVal = value(m1.group(2));
String label = null;
Test test = null;
int expVal = 0;
} else if (m2.find()) {
label = value.substring(0, m2.start());
try {
LabelVote v = LabelVote.parse(value);
test = Test.EQ;
expVal = value(m2.group(1));
label = v.getLabel();
expVal = v.getValue();
} catch (IllegalArgumentException e) {
// Try next format.
}
} else {
label = value;
try {
LabelVote v = LabelVote.parseWithEquals(value);
test = Test.EQ;
expVal = 1;
label = v.getLabel();
expVal = v.getValue();
} catch (IllegalArgumentException e) {
// Try next format.
}
if (label == null) {
Matcher m = Pattern.compile("(>=|<=)([+-]?\\d+)$").matcher(value);
if (m.find()) {
label = value.substring(0, m.start());
test = Test.op(m.group(1));
expVal = value(m.group(2));
} else {
label = value;
test = Test.EQ;
expVal = 1;
}
}
List<Predicate<ChangeData>> r = Lists.newArrayListWithCapacity(2 * MAX_LABEL_VALUE);

View File

@@ -0,0 +1,109 @@
// Copyright (C) 2013 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.gerrit.server.util;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.gerrit.common.data.LabelType;
/** A single vote on a label, consisting of a label name and a value. */
public class LabelVote {
public static LabelVote parse(String text) {
checkArgument(!Strings.isNullOrEmpty(text), "Empty label vote");
if (text.charAt(0) == '-') {
return new LabelVote(text.substring(1), (short) 0);
}
short sign = 0;
int i;
for (i = text.length() - 1; i >= 0; i--) {
int c = text.charAt(i);
if (c == '-') {
sign = (short) -1;
break;
} else if (c == '+') {
sign = (short) 1;
break;
} else if (!('0' <= c && c <= '9')) {
break;
}
}
if (sign == 0) {
return new LabelVote(text, (short) 1);
}
return new LabelVote(text.substring(0, i),
(short)(sign * Short.parseShort(text.substring(i + 1))));
}
public static LabelVote parseWithEquals(String text) {
checkArgument(!Strings.isNullOrEmpty(text), "Empty label vote");
int e = text.lastIndexOf('=');
checkArgument(e >= 0, "Label vote missing '=': %s", text);
return new LabelVote(text.substring(0, e),
Short.parseShort(text.substring(e + 1), text.length()));
}
private final String name;
private final short value;
public LabelVote(String name, short value) {
this.name = LabelType.checkName(name);
this.value = value;
}
public String getLabel() {
return name;
}
public short getValue() {
return value;
}
public String format() {
if (value == (short) 0) {
return '-' + name;
} else if (value == (short) 1) {
return name;
} else if (value < 0) {
return name + value;
} else {
return name + '+' + value;
}
}
public String formatWithEquals() {
if (value <= (short) 0) {
return name + '=' + value;
} else {
return name + "=+" + value;
}
}
@Override
public boolean equals(Object o) {
if (o instanceof LabelVote) {
LabelVote l = (LabelVote) o;
return Objects.equal(name, l.name)
&& value == l.value;
}
return false;
}
@Override
public String toString() {
return format();
}
}