// Copyright (C) 2010 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.query.change; import com.google.common.collect.Lists; import com.google.gerrit.reviewdb.client.Account; import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.reviewdb.server.ReviewDb; import com.google.gerrit.server.IdentifiedUser; 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.gerrit.server.util.RangeUtil; import com.google.gerrit.server.util.RangeUtil.Range; import com.google.inject.Provider; import java.util.List; import java.util.Set; public class LabelPredicate extends OrPredicate<ChangeData> { private static final int MAX_LABEL_VALUE = 4; static class Args { final ProjectCache projectCache; final ChangeControl.GenericFactory ccFactory; final IdentifiedUser.GenericFactory userFactory; final Provider<ReviewDb> dbProvider; final String value; final Set<Account.Id> accounts; final AccountGroup.UUID group; private Args( ProjectCache projectCache, ChangeControl.GenericFactory ccFactory, IdentifiedUser.GenericFactory userFactory, Provider<ReviewDb> dbProvider, String value, Set<Account.Id> accounts, AccountGroup.UUID group) { this.projectCache = projectCache; this.ccFactory = ccFactory; this.userFactory = userFactory; this.dbProvider = dbProvider; this.value = value; this.accounts = accounts; this.group = group; } } private static class Parsed { private final String label; private final String test; private final int expVal; private Parsed(String label, String test, int expVal) { this.label = label; this.test = test; this.expVal = expVal; } } private final String value; LabelPredicate(ProjectCache projectCache, ChangeControl.GenericFactory ccFactory, IdentifiedUser.GenericFactory userFactory, Provider<ReviewDb> dbProvider, String value, Set<Account.Id> accounts, AccountGroup.UUID group) { super(predicates(new Args(projectCache, ccFactory, userFactory, dbProvider, value, accounts, group))); this.value = value; } private static List<Predicate<ChangeData>> predicates(Args args) { String v = args.value; Parsed parsed = null; try { LabelVote lv = LabelVote.parse(v); parsed = new Parsed(lv.getLabel(), "=", lv.getValue()); } catch (IllegalArgumentException e) { // Try next format. } try { LabelVote lv = LabelVote.parseWithEquals(v); parsed = new Parsed(lv.getLabel(), "=", lv.getValue()); } catch (IllegalArgumentException e) { // Try next format. } Range range; if (parsed == null) { range = RangeUtil.getRange(v, -MAX_LABEL_VALUE, MAX_LABEL_VALUE); if (range == null) { range = new Range(v, 1, 1); } } else { range = RangeUtil.getRange( parsed.label, parsed.test, parsed.expVal, -MAX_LABEL_VALUE, MAX_LABEL_VALUE); } String prefix = range.prefix; int min = range.min; int max = range.max; List<Predicate<ChangeData>> r = Lists.newArrayListWithCapacity(max - min + 1); for (int i = min; i <= max; i++) { r.add(onePredicate(args, prefix, i)); } return r; } private static Predicate<ChangeData> onePredicate(Args args, String label, int expVal) { if (expVal != 0) { return equalsLabelPredicate(args, label, expVal); } else { return noLabelQuery(args, label); } } private static Predicate<ChangeData> noLabelQuery(Args args, String label) { List<Predicate<ChangeData>> r = Lists.newArrayListWithCapacity(2 * MAX_LABEL_VALUE); for (int i = 1; i <= MAX_LABEL_VALUE; i++) { r.add(not(equalsLabelPredicate(args, label, i))); r.add(not(equalsLabelPredicate(args, label, -i))); } return and(r); } private static Predicate<ChangeData> equalsLabelPredicate(Args args, String label, int expVal) { if (args.accounts == null || args.accounts.isEmpty()) { return new EqualsLabelPredicate(args, label, expVal, null); } else { List<Predicate<ChangeData>> r = Lists.newArrayList(); for (Account.Id a : args.accounts) { r.add(new EqualsLabelPredicate(args, label, expVal, a)); } return or(r); } } @Override public String toString() { return ChangeQueryBuilder.FIELD_LABEL + ":" + value; } }