aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties5
-rw-r--r--sonar-core/src/main/java/org/sonar/core/measure/MeasureFilter.java4
-rw-r--r--sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterCondition.java27
-rw-r--r--sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterFactory.java30
-rw-r--r--sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSql.java4
-rw-r--r--sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterConditionTest.java21
-rw-r--r--sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterFactoryTest.java18
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/measures/_sidebar.html.erb13
8 files changed, 111 insertions, 11 deletions
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
index 9c725a979a7..c88d7a7158c 100644
--- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
@@ -417,6 +417,10 @@ measure_filter.criteria.name=Name
measure_filter.criteria.language=Language
measure_filter.criteria.metric=Metric
measure_filter.criteria.project=Project
+measure_filter.criteria.alert=Alert
+measure_filter.criteria.alert.error=Error
+measure_filter.criteria.alert.warn=Warning
+measure_filter.criteria.alert.ok=Ok
measure_filter.criteria.from_date=Inspected since
measure_filter.criteria.to_date=Inspected before
measure_filter.criteria.date_format=year-month-day (2013-01-31)
@@ -430,6 +434,7 @@ measure_filter.new_search=New search
measure_filter.favourite_filters=Favourite Filters
measure_filter.more_criteria=+ More Criteria
measure_filter.languages=Languages
+measure_filter.alert_levels=Alert levels
measure_filter.col.date=Date
measure_filter.col.description=Description
measure_filter.col.key=Key
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilter.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilter.java
index 1dcbcd66021..67108a4eb31 100644
--- a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilter.java
+++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilter.java
@@ -196,12 +196,12 @@ public class MeasureFilter {
}
public boolean isEmpty() {
- return resourceQualifiers.isEmpty() && resourceScopes.isEmpty() && StringUtils.isEmpty(baseResourceKey) && baseResourceId==null && !userFavourites;
+ return resourceQualifiers.isEmpty() && resourceScopes.isEmpty() && StringUtils.isEmpty(baseResourceKey) && baseResourceId == null && !userFavourites;
}
@VisibleForTesting
static List<String> sanitize(@Nullable List<String> list) {
- return isEmptyList(list) ? Collections.<String>emptyList() : Lists.newArrayList(list);
+ return isEmptyList(list) ? Collections.<String> emptyList() : Lists.newArrayList(list);
}
private static boolean isEmptyList(@Nullable List<String> list) {
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterCondition.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterCondition.java
index 39f5903f884..bbf2c7ed869 100644
--- a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterCondition.java
+++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterCondition.java
@@ -25,7 +25,7 @@ import org.sonar.api.measures.Metric;
public class MeasureFilterCondition {
public enum Operator {
- EQUALS("eq", "="), GREATER("gt", ">"), GREATER_OR_EQUALS("gte", ">="), LESS("lt", "<"), LESS_OR_EQUALS("lte", "<=");
+ EQUALS("eq", "="), GREATER("gt", ">"), GREATER_OR_EQUALS("gte", ">="), LESS("lt", "<"), LESS_OR_EQUALS("lte", "<="), IN("in", "IN");
private String code;
private String sql;
@@ -52,12 +52,21 @@ public class MeasureFilterCondition {
private final Metric metric;
private final Operator operator;
private final double value;
+ private final String textValue;
private Integer period = null;
public MeasureFilterCondition(Metric metric, Operator operator, double value) {
this.metric = metric;
this.operator = operator;
this.value = value;
+ this.textValue = null;
+ }
+
+ public MeasureFilterCondition(Metric metric, Operator operator, String textValue) {
+ this.metric = metric;
+ this.operator = operator;
+ this.value = 0;
+ this.textValue = textValue;
}
public MeasureFilterCondition setPeriod(Integer period) {
@@ -77,6 +86,10 @@ public class MeasureFilterCondition {
return value;
}
+ public String textValue() {
+ return textValue;
+ }
+
public Integer period() {
return period;
}
@@ -85,8 +98,10 @@ public class MeasureFilterCondition {
sb.append("pmcond").append(conditionIndex);
if (period != null) {
sb.append(".variation_value_").append(period).toString();
- } else {
+ } else if (textValue == null) {
sb.append(".value");
+ } else {
+ sb.append(".text_value");
}
return sb;
}
@@ -97,7 +112,13 @@ public class MeasureFilterCondition {
sql.append(metric.getId());
sql.append(" AND ");
appendSqlColumn(sql, conditionIndex);
- sql.append(operator.getSql()).append(value);
+ sql.append(" ").append(operator.getSql()).append(" ");
+ if (textValue == null) {
+ sql.append(value);
+ }
+ else {
+ sql.append(textValue);
+ }
sql.append(" AND ");
sql.append(table).append(".rule_id IS NULL AND ");
sql.append(table).append(".rule_priority IS NULL AND ");
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterFactory.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterFactory.java
index 08d0cc043c9..ce0ca32382e 100644
--- a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterFactory.java
+++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterFactory.java
@@ -19,9 +19,13 @@
*/
package org.sonar.core.measure;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.ServerComponent;
+import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.utils.DateUtils;
@@ -51,6 +55,10 @@ public class MeasureFilterFactory implements ServerComponent {
filter.setResourceScopes(toList(properties.get("scopes")));
filter.setResourceQualifiers(toList(properties.get("qualifiers")));
filter.setResourceLanguages(toList(properties.get("languages")));
+ MeasureFilterCondition condition = alertToCondition((toList(properties.get("alertLevels"))));
+ if (condition != null) {
+ filter.addCondition(condition);
+ }
if (properties.containsKey("onBaseComponents")) {
filter.setOnBaseResourceChildren(Boolean.valueOf((String) properties.get("onBaseComponents")));
}
@@ -126,6 +134,28 @@ public class MeasureFilterFactory implements ServerComponent {
return condition;
}
+ private MeasureFilterCondition alertToCondition(List<String> alertLevels) {
+ if (alertLevels == null || alertLevels.isEmpty()) {
+ return null;
+ }
+ MeasureFilterCondition condition = null;
+ String metricKey = CoreMetrics.ALERT_STATUS_KEY;
+ String op = "in";
+ List<String> alertLevelsUppercase = Lists.transform(alertLevels, new Function<String, String>() {
+ @Override
+ public String apply(String input) {
+ return input != null ? input.toUpperCase() : "";
+ }
+ });
+ String val = "(\"" + Joiner.on("\", \"").join(alertLevelsUppercase) + "\")";
+ if (!Strings.isNullOrEmpty(metricKey) && !Strings.isNullOrEmpty(op) && !Strings.isNullOrEmpty(val)) {
+ Metric metric = metricFinder.findByKey(metricKey);
+ MeasureFilterCondition.Operator operator = MeasureFilterCondition.Operator.fromCode(op);
+ condition = new MeasureFilterCondition(metric, operator, val);
+ }
+ return condition;
+ }
+
private List<String> toList(@Nullable Object obj) {
List<String> result = null;
if (obj != null) {
diff --git a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSql.java b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSql.java
index 6b8b877b285..8545d98be8f 100644
--- a/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSql.java
+++ b/sonar-core/src/main/java/org/sonar/core/measure/MeasureFilterSql.java
@@ -211,8 +211,8 @@ class MeasureFilterSql {
private static void appendInStatement(List<String> values, StringBuilder to) {
to.append(" (");
- for (int i=0 ; i<values.size() ; i++) {
- if (i>0) {
+ for (int i = 0; i < values.size(); i++) {
+ if (i > 0) {
to.append(",");
}
to.append("'");
diff --git a/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterConditionTest.java b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterConditionTest.java
index 656660d1ffb..a6bfdee3a17 100644
--- a/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterConditionTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterConditionTest.java
@@ -59,9 +59,10 @@ public class MeasureFilterConditionTest {
assertThat(condition.operator()).isEqualTo(MeasureFilterCondition.Operator.GREATER);
assertThat(condition.period()).isNull();
assertThat(condition.value()).isEqualTo(10.0);
+ assertThat(condition.textValue()).isNull();
assertThat(condition.appendSqlColumn(new StringBuilder(), 1).toString()).isEqualTo("pmcond1.value");
assertThat(condition.toString()).isNotEmpty();
- assertThat(condition.appendSqlCondition(new StringBuilder(), 1).toString()).isEqualTo(" pmcond1.metric_id=123 AND pmcond1.value>10.0 AND pmcond1.rule_id IS NULL AND pmcond1.rule_priority IS NULL AND pmcond1.characteristic_id IS NULL AND pmcond1.person_id IS NULL ");
+ assertThat(condition.appendSqlCondition(new StringBuilder(), 1).toString()).isEqualTo(" pmcond1.metric_id=123 AND pmcond1.value > 10.0 AND pmcond1.rule_id IS NULL AND pmcond1.rule_priority IS NULL AND pmcond1.characteristic_id IS NULL AND pmcond1.person_id IS NULL ");
}
@Test
@@ -77,6 +78,22 @@ public class MeasureFilterConditionTest {
assertThat(condition.value()).isEqualTo(10.0);
assertThat(condition.appendSqlColumn(new StringBuilder(), 2).toString()).isEqualTo("pmcond2.variation_value_3");
assertThat(condition.toString()).isNotEmpty();
- assertThat(condition.appendSqlCondition(new StringBuilder(), 2).toString()).isEqualTo(" pmcond2.metric_id=123 AND pmcond2.variation_value_3<=10.0 AND pmcond2.rule_id IS NULL AND pmcond2.rule_priority IS NULL AND pmcond2.characteristic_id IS NULL AND pmcond2.person_id IS NULL ");
+ assertThat(condition.appendSqlCondition(new StringBuilder(), 2).toString()).isEqualTo(" pmcond2.metric_id=123 AND pmcond2.variation_value_3 <= 10.0 AND pmcond2.rule_id IS NULL AND pmcond2.rule_priority IS NULL AND pmcond2.characteristic_id IS NULL AND pmcond2.person_id IS NULL ");
+ }
+
+ @Test
+ public void text_value_condition() {
+ Metric ncloc = new Metric.Builder("ncloc", "NCLOC", Metric.ValueType.INT).create();
+ ncloc.setId(123);
+ MeasureFilterCondition condition = new MeasureFilterCondition(ncloc, MeasureFilterCondition.Operator.EQUALS, "\"foo\"");
+
+ assertThat(condition.metric()).isEqualTo(ncloc);
+ assertThat(condition.operator()).isEqualTo(MeasureFilterCondition.Operator.EQUALS);
+ assertThat(condition.period()).isNull();
+ assertThat(condition.value()).isEqualTo(0);
+ assertThat(condition.textValue()).isEqualTo("\"foo\"");
+ assertThat(condition.appendSqlColumn(new StringBuilder(), 1).toString()).isEqualTo("pmcond1.text_value");
+ assertThat(condition.toString()).isNotEmpty();
+ assertThat(condition.appendSqlCondition(new StringBuilder(), 1).toString()).isEqualTo(" pmcond1.metric_id=123 AND pmcond1.text_value = \"foo\" AND pmcond1.rule_id IS NULL AND pmcond1.rule_priority IS NULL AND pmcond1.characteristic_id IS NULL AND pmcond1.person_id IS NULL ");
}
}
diff --git a/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterFactoryTest.java b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterFactoryTest.java
index ac5210d01db..c6f1da2e8e0 100644
--- a/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterFactoryTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/measure/MeasureFilterFactoryTest.java
@@ -28,6 +28,7 @@ import org.sonar.api.measures.Metric;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.utils.DateUtils;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -174,6 +175,23 @@ public class MeasureFilterFactoryTest {
}
@Test
+ public void alert_level_condition() {
+ MeasureFilterFactory factory = new MeasureFilterFactory(newMetricFinder());
+ Map<String, Object> props = ImmutableMap.<String, Object>of(
+ "alertLevels", Arrays.asList("error", "warn")
+ );
+ MeasureFilter filter = factory.create(props);
+
+ List<MeasureFilterCondition> conditions = filter.getMeasureConditions();
+ assertThat(conditions).hasSize(1);
+ assertThat(conditions.get(0).metric().getKey()).isEqualTo("alert_status");
+ assertThat(conditions.get(0).operator()).isEqualTo(MeasureFilterCondition.Operator.IN);
+ assertThat(conditions.get(0).value()).isEqualTo(0);
+ assertThat(conditions.get(0).textValue()).isEqualTo("(\"ERROR\", \"WARN\")");
+ assertThat(conditions.get(0).period()).isNull();
+ }
+
+ @Test
public void ignore_partial_measure_condition() {
MeasureFilterFactory factory = new MeasureFilterFactory(newMetricFinder());
Map<String, Object> props = ImmutableMap.<String, Object>of(
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/measures/_sidebar.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/measures/_sidebar.html.erb
index 78a91d4620b..eca9640c027 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/measures/_sidebar.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/measures/_sidebar.html.erb
@@ -28,13 +28,14 @@
var hiddenConditionIndexes = [<%= hidden_condition_indexes.join(',') -%>];
$j(document).ready(function () {
$j('#select-lang').select2({allowClear: true, width: '100%', placeholder: '<%= escape_javascript message 'measure_filter.languages' -%>'});
+ $j('#select-alert').select2({allowClear: true, width: '100%', placeholder: '<%= escape_javascript message 'measure_filter.alert_levels' -%>'});
$j('#select-qualifiers').select2({allowClear: true, width: '100%', placeholder: '<%= escape_javascript message('measure_filter.criteria.what') -%>'});
$j('#more-criteria')
.select2({allowClear: true, width: '100%', placeholder: '<%= message 'measure_filter.more_criteria' -%>'})
.on("change", function (e) {
$j("#criteria-" + e.val).insertBefore($j("#more-td")).show();
- if (e.val == 'lang' || e.val == 'project') {
+ if (e.val == 'lang' || e.val == 'project' || e.val == 'alert') {
$j("#select-" + e.val).select2("enable");
$j("#select-" + e.val).select2("focus");
} else if (e.val == 'fav') {
@@ -140,6 +141,11 @@
<%= check_box_tag 'onFavourites', 'true', @filter.criteria['onFavourites']=='true', :id => 'check-fav' -%>
</li>
+ <li id="criteria-alert" <%= "style='display:none'" unless @filter.criteria('alertLevels') -%> class="marginbottom5">
+ <% alertLevels = [['', '']].concat(['error', 'warn', 'ok'].map { |level| [message('measure_filter.criteria.alert.' + level), level] }) %>
+ <%= select_tag 'alertLevels[]', options_for_select(alertLevels, @filter.criteria['alertLevels']), :multiple => true, :id => 'select-alert' -%>
+ </li>
+
<%
condition_metrics = Metric.all.select { |m| m.numeric? && !m.hidden }
for i in 1..3
@@ -212,6 +218,9 @@
<% unless @filter.base_resource %>
<option value="project"><%= message 'measure_filter.criteria.components_of_project' -%></option>
<% end %>
+ <% unless @filter.criteria('alertLevels') %>
+ <option value="alert"><%= message 'measure_filter.criteria.alert' -%></option>
+ <% end %>
</select>
</li>
<li>
@@ -221,4 +230,4 @@
<% end %>
</li>
</form>
-</ul> \ No newline at end of file
+</ul>