Line data Source code
1 : // Copyright (C) 2008 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.entities; 16 : 17 : import static java.util.Comparator.comparing; 18 : import static java.util.stream.Collectors.toList; 19 : 20 : import com.google.auto.value.AutoValue; 21 : import com.google.common.collect.ImmutableList; 22 : import com.google.common.collect.ImmutableMap; 23 : import com.google.gerrit.common.Nullable; 24 : import java.util.ArrayList; 25 : import java.util.List; 26 : import java.util.Optional; 27 : 28 : @AutoValue 29 154 : public abstract class LabelType { 30 : public static final boolean DEF_ALLOW_POST_SUBMIT = true; 31 : public static final boolean DEF_CAN_OVERRIDE = true; 32 : public static final boolean DEF_IGNORE_SELF_APPROVAL = false; 33 : 34 : public static LabelType withDefaultValues(String name) { 35 1 : checkName(name); 36 1 : List<LabelValue> values = new ArrayList<>(2); 37 1 : values.add(LabelValue.create((short) 0, "Rejected")); 38 1 : values.add(LabelValue.create((short) 1, "Approved")); 39 1 : return create(name, values); 40 : } 41 : 42 : public static String checkName(String name) throws IllegalArgumentException { 43 154 : checkNameInternal(name); 44 154 : if ("SUBM".equals(name)) { 45 0 : throw new IllegalArgumentException("Reserved label name \"" + name + "\""); 46 : } 47 154 : return name; 48 : } 49 : 50 : public static String checkNameInternal(String name) throws IllegalArgumentException { 51 154 : if (name == null || name.isEmpty()) { 52 1 : throw new IllegalArgumentException("Empty label name"); 53 : } 54 154 : for (int i = 0; i < name.length(); i++) { 55 154 : char c = name.charAt(i); 56 154 : if ((i == 0 && c == '-') 57 : || !((c >= 'a' && c <= 'z') 58 : || (c >= 'A' && c <= 'Z') 59 : || (c >= '0' && c <= '9') 60 : || c == '-')) { 61 13 : throw new IllegalArgumentException("Illegal label name \"" + name + "\""); 62 : } 63 : } 64 154 : return name; 65 : } 66 : 67 : private static ImmutableList<LabelValue> sortValues(List<LabelValue> values) { 68 154 : if (values.isEmpty()) { 69 5 : return ImmutableList.of(); 70 : } 71 154 : values = values.stream().sorted(comparing(LabelValue::getValue)).collect(toList()); 72 154 : short v = values.get(0).getValue(); 73 154 : short i = 0; 74 154 : ImmutableList.Builder<LabelValue> result = ImmutableList.builder(); 75 : // Fill in any missing values with empty text. 76 154 : while (i < values.size()) { 77 154 : while (v < values.get(i).getValue()) { 78 1 : result.add(LabelValue.create(v++, "")); 79 : } 80 154 : v++; 81 154 : result.add(values.get(i++)); 82 : } 83 154 : return result.build(); 84 : } 85 : 86 : public abstract String getName(); 87 : 88 : public abstract Optional<String> getDescription(); 89 : 90 : public abstract LabelFunction getFunction(); 91 : 92 : public abstract boolean isAllowPostSubmit(); 93 : 94 : public abstract boolean isIgnoreSelfApproval(); 95 : 96 : public abstract short getDefaultValue(); 97 : 98 : public abstract ImmutableList<LabelValue> getValues(); 99 : 100 : public abstract short getMaxNegative(); 101 : 102 : public abstract short getMaxPositive(); 103 : 104 : public abstract boolean isCanOverride(); 105 : 106 : public abstract Optional<String> getCopyCondition(); 107 : 108 : @Nullable 109 : public abstract ImmutableList<String> getRefPatterns(); 110 : 111 : public abstract ImmutableMap<Short, LabelValue> getByValue(); 112 : 113 : public static LabelType create(String name, List<LabelValue> valueList) { 114 4 : return LabelType.builder(name, valueList).build(); 115 : } 116 : 117 : public static LabelType.Builder builder(String name, List<LabelValue> valueList) { 118 154 : return new AutoValue_LabelType.Builder() 119 154 : .setName(name) 120 154 : .setDescription(Optional.empty()) 121 154 : .setValues(valueList) 122 154 : .setDefaultValue((short) 0) 123 154 : .setFunction(LabelFunction.MAX_WITH_BLOCK) 124 154 : .setMaxNegative(Short.MIN_VALUE) 125 154 : .setMaxPositive(Short.MAX_VALUE) 126 154 : .setCanOverride(DEF_CAN_OVERRIDE) 127 154 : .setAllowPostSubmit(DEF_ALLOW_POST_SUBMIT) 128 154 : .setIgnoreSelfApproval(DEF_IGNORE_SELF_APPROVAL); 129 : } 130 : 131 : public boolean matches(PatchSetApproval psa) { 132 58 : return psa.labelId().get().equalsIgnoreCase(getName()); 133 : } 134 : 135 : @Nullable 136 : public LabelValue getMin() { 137 60 : if (getValues().isEmpty()) { 138 0 : return null; 139 : } 140 60 : return getValues().get(0); 141 : } 142 : 143 : @Nullable 144 : public LabelValue getMax() { 145 60 : if (getValues().isEmpty()) { 146 0 : return null; 147 : } 148 60 : return getValues().get(getValues().size() - 1); 149 : } 150 : 151 : public boolean isMaxNegative(PatchSetApproval ca) { 152 58 : return isMaxNegative(ca.value()); 153 : } 154 : 155 : public boolean isMaxNegative(short value) { 156 58 : return getMaxNegative() == value; 157 : } 158 : 159 : public boolean isMaxPositive(PatchSetApproval ca) { 160 59 : return isMaxPositive(ca.value()); 161 : } 162 : 163 : public boolean isMaxPositive(short value) { 164 59 : return getMaxPositive() == value; 165 : } 166 : 167 : public LabelValue getValue(short value) { 168 58 : return getByValue().get(value); 169 : } 170 : 171 : public LabelValue getValue(PatchSetApproval ca) { 172 46 : return getByValue().get(ca.value()); 173 : } 174 : 175 : public LabelId getLabelId() { 176 74 : return LabelId.create(getName()); 177 : } 178 : 179 : @Override 180 : public final String toString() { 181 0 : StringBuilder sb = new StringBuilder(getName()).append('['); 182 0 : LabelValue min = getMin(); 183 0 : LabelValue max = getMax(); 184 0 : if (min != null && max != null) { 185 0 : sb.append( 186 0 : new PermissionRange(Permission.forLabel(getName()), min.getValue(), max.getValue()) 187 0 : .toString() 188 0 : .trim()); 189 0 : } else if (min != null) { 190 0 : sb.append(min.formatValue().trim()); 191 0 : } else if (max != null) { 192 0 : sb.append(max.formatValue().trim()); 193 : } 194 0 : sb.append(']'); 195 0 : return sb.toString(); 196 : } 197 : 198 : public abstract Builder toBuilder(); 199 : 200 : @AutoValue.Builder 201 154 : public abstract static class Builder { 202 : public abstract Builder setName(String name); 203 : 204 : public abstract Builder setDescription(Optional<String> description); 205 : 206 : public abstract Builder setFunction(LabelFunction function); 207 : 208 : public abstract Builder setCanOverride(boolean canOverride); 209 : 210 : public abstract Builder setAllowPostSubmit(boolean allowPostSubmit); 211 : 212 : public abstract Builder setIgnoreSelfApproval(boolean ignoreSelfApproval); 213 : 214 : public abstract Builder setRefPatterns(@Nullable List<String> refPatterns); 215 : 216 : public abstract Builder setValues(List<LabelValue> values); 217 : 218 : public abstract Builder setDefaultValue(short defaultValue); 219 : 220 : public abstract Builder setCopyCondition(@Nullable String copyCondition); 221 : 222 : public abstract Builder setMaxNegative(short maxNegative); 223 : 224 : public abstract Builder setMaxPositive(short maxPositive); 225 : 226 : public abstract ImmutableList<LabelValue> getValues(); 227 : 228 : protected abstract String getName(); 229 : 230 : protected abstract Builder setByValue(ImmutableMap<Short, LabelValue> byValue); 231 : 232 : @Nullable 233 : protected abstract ImmutableList<String> getRefPatterns(); 234 : 235 : protected abstract LabelType autoBuild(); 236 : 237 : public LabelType build() throws IllegalArgumentException { 238 154 : setName(checkName(getName())); 239 154 : if (getRefPatterns() == null || getRefPatterns().isEmpty()) { 240 : // Empty to null 241 154 : setRefPatterns(null); 242 : } 243 : 244 154 : List<LabelValue> valueList = sortValues(getValues()); 245 154 : setValues(valueList); 246 154 : if (!valueList.isEmpty()) { 247 154 : if (valueList.get(0).getValue() < 0) { 248 153 : setMaxNegative(valueList.get(0).getValue()); 249 : } 250 154 : if (valueList.get(valueList.size() - 1).getValue() > 0) { 251 154 : setMaxPositive(valueList.get(valueList.size() - 1).getValue()); 252 : } 253 : } 254 : 255 154 : ImmutableMap.Builder<Short, LabelValue> byValue = ImmutableMap.builder(); 256 154 : for (LabelValue v : valueList) { 257 154 : byValue.put(v.getValue(), v); 258 154 : } 259 154 : setByValue(byValue.build()); 260 : 261 154 : return autoBuild(); 262 : } 263 : } 264 : }