3 * Copyright (C) 2009-2019 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.ce.task.projectanalysis.qualitygate;
22 import java.util.Optional;
23 import javax.annotation.CheckForNull;
24 import org.sonar.ce.task.projectanalysis.measure.Measure;
25 import org.sonar.ce.task.projectanalysis.metric.Metric;
27 import static com.google.common.base.Preconditions.checkArgument;
28 import static java.util.Optional.of;
30 public final class ConditionEvaluator {
33 * Evaluates the condition for the specified measure
35 public EvaluationResult evaluate(Condition condition, Measure measure) {
36 checkArgument(condition.getMetric().getType() != Metric.MetricType.DATA, "Conditions on MetricType DATA are not supported");
38 Comparable measureComparable = parseMeasure(condition, measure);
39 if (measureComparable == null) {
40 return new EvaluationResult(Measure.Level.OK, null);
43 return evaluateCondition(condition, measureComparable)
44 .orElseGet(() -> new EvaluationResult(Measure.Level.OK, measureComparable));
47 private static Optional<EvaluationResult> evaluateCondition(Condition condition, Comparable<?> measureComparable) {
49 Comparable conditionComparable = parseConditionValue(condition.getMetric(), condition.getErrorThreshold());
50 if (doesReachThresholds(measureComparable, conditionComparable, condition)) {
51 return of(new EvaluationResult(Measure.Level.ERROR, measureComparable));
53 return Optional.empty();
54 } catch (NumberFormatException badValueFormat) {
55 throw new IllegalArgumentException(String.format(
56 "Quality Gate: Unable to parse value '%s' to compare against %s",
57 condition.getErrorThreshold(), condition.getMetric().getName()));
61 private static boolean doesReachThresholds(Comparable measureValue, Comparable criteriaValue, Condition condition) {
62 int comparison = measureValue.compareTo(criteriaValue);
63 switch (condition.getOperator()) {
65 return comparison == 0;
67 return comparison != 0;
69 return comparison > 0;
71 return comparison < 0;
73 throw new IllegalArgumentException(String.format("Unsupported operator '%s'", condition.getOperator()));
77 private static Comparable parseConditionValue(Metric metric, String value) {
78 switch (metric.getType().getValueType()) {
80 return Integer.parseInt(value) == 1;
82 return parseInteger(value);
84 return Long.parseLong(value);
86 return Double.parseDouble(value);
91 throw new IllegalArgumentException(String.format("Unsupported value type %s. Can not convert condition value", metric.getType().getValueType()));
95 private static Comparable<Integer> parseInteger(String value) {
96 return value.contains(".") ? Integer.parseInt(value.substring(0, value.indexOf('.'))) : Integer.parseInt(value);
100 private static Comparable parseMeasure(Condition condition, Measure measure) {
101 if (condition.useVariation()) {
102 return parseMeasureFromVariation(condition, measure);
104 switch (measure.getValueType()) {
106 return measure.getBooleanValue();
108 return measure.getIntValue();
110 return measure.getLongValue();
112 return measure.getDoubleValue();
114 return measure.getStringValue();
116 return measure.getLevelValue().name();
120 throw new IllegalArgumentException(
121 String.format("Unsupported measure ValueType %s. Can not parse measure to a Comparable", measure.getValueType()));
126 private static Comparable parseMeasureFromVariation(Condition condition, Measure measure) {
127 if (!measure.hasVariation()) {
131 Double variation = measure.getVariation();
132 Metric.MetricType metricType = condition.getMetric().getType();
133 switch (metricType.getValueType()) {
135 return variation.intValue() == 1;
137 return variation.intValue();
139 return variation.longValue();
146 throw new IllegalArgumentException("Unsupported metric type " + metricType);