Line data Source code
1 : // Copyright (C) 2021 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.query.change; 16 : 17 : import com.google.gerrit.common.Nullable; 18 : import com.google.gerrit.entities.Account; 19 : import com.google.gerrit.entities.Change; 20 : import com.google.gerrit.entities.LabelType; 21 : import com.google.gerrit.entities.LabelTypes; 22 : import com.google.gerrit.entities.LabelValue; 23 : import com.google.gerrit.index.query.Predicate; 24 : import com.google.gerrit.server.index.change.ChangeField; 25 : import com.google.gerrit.server.project.ProjectState; 26 : import java.util.ArrayList; 27 : import java.util.List; 28 : import java.util.Optional; 29 : 30 : public class MagicLabelPredicate extends ChangeIndexPredicate { 31 : protected final LabelPredicate.Args args; 32 : private final MagicLabelVote magicLabelVote; 33 : private final Account.Id account; 34 : @Nullable private final Integer count; 35 : 36 : public MagicLabelPredicate( 37 : LabelPredicate.Args args, 38 : MagicLabelVote magicLabelVote, 39 : Account.Id account, 40 : @Nullable Integer count) { 41 7 : super( 42 : ChangeField.LABEL, 43 7 : ChangeField.formatLabel( 44 7 : magicLabelVote.label(), magicLabelVote.value().name(), account, count)); 45 7 : this.account = account; 46 7 : this.args = args; 47 7 : this.magicLabelVote = magicLabelVote; 48 7 : this.count = count; 49 7 : } 50 : 51 : @Override 52 : public boolean match(ChangeData changeData) { 53 4 : Change change = changeData.change(); 54 4 : if (change == null) { 55 : // The change has disappeared. 56 : // 57 0 : return false; 58 : } 59 : 60 4 : Optional<ProjectState> project = args.projectCache.get(change.getDest().project()); 61 4 : if (!project.isPresent()) { 62 : // The project has disappeared. 63 : // 64 0 : return false; 65 : } 66 : 67 4 : LabelType labelType = type(project.get().getLabelTypes(), magicLabelVote.label()); 68 4 : if (labelType == null) { 69 0 : return false; // Label is not defined by this project. 70 : } 71 : 72 4 : switch (magicLabelVote.value()) { 73 : case ANY: 74 3 : return matchAny(changeData, labelType); 75 : case MIN: 76 3 : return matchNumeric(changeData, magicLabelVote.label(), labelType.getMin().getValue()); 77 : case MAX: 78 4 : return matchNumeric(changeData, magicLabelVote.label(), labelType.getMax().getValue()); 79 : } 80 : 81 0 : throw new IllegalStateException("Unsupported magic label value: " + magicLabelVote.value()); 82 : } 83 : 84 : private boolean matchAny(ChangeData changeData, LabelType labelType) { 85 3 : List<Predicate<ChangeData>> predicates = new ArrayList<>(); 86 3 : for (LabelValue labelValue : labelType.getValues()) { 87 3 : if (labelValue.getValue() != 0) { 88 3 : predicates.add(numericPredicate(labelType.getName(), labelValue.getValue())); 89 : } 90 3 : } 91 3 : return or(predicates).asMatchable().match(changeData); 92 : } 93 : 94 : private boolean matchNumeric(ChangeData changeData, String label, short value) { 95 4 : return numericPredicate(label, value).match(changeData); 96 : } 97 : 98 : private EqualsLabelPredicate numericPredicate(String label, short value) { 99 4 : return new EqualsLabelPredicate(args, label, value, account, count); 100 : } 101 : 102 : @Nullable 103 : protected static LabelType type(LabelTypes types, String toFind) { 104 4 : if (types.byLabel(toFind).isPresent()) { 105 4 : return types.byLabel(toFind).get(); 106 : } 107 : 108 0 : for (LabelType lt : types.getLabelTypes()) { 109 0 : if (toFind.equalsIgnoreCase(lt.getName())) { 110 0 : return lt; 111 : } 112 0 : } 113 0 : return null; 114 : } 115 : }