From 08748e9a991f3c1c91523f5ea28068872dd5803f Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Tue, 17 May 2016 14:53:48 +0200 Subject: [PATCH] SONAR-7576 api/measures/component_tree filter component based on period or absolute value --- .../measure/ws/ComponentTreeDataLoader.java | 19 +---- .../sonar/server/measure/ws/HasMeasure.java | 80 +++++++++++++++++++ .../measure/ws/ComponentTreeActionTest.java | 41 +++++++++- 3 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/measure/ws/HasMeasure.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java index 196e21d2bf9..7397e2cfe6d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java @@ -137,7 +137,7 @@ public class ComponentTreeDataLoader { } } - private int computeComponentCount(int dbComponentCount, List components, boolean returnOnlyComponentsWithMeasures) { + private static int computeComponentCount(int dbComponentCount, List components, boolean returnOnlyComponentsWithMeasures) { return returnOnlyComponentsWithMeasures ? components.size() : dbComponentCount; } @@ -269,7 +269,7 @@ public class ComponentTreeDataLoader { checkState(metricToSort.isPresent(), "Metric '%s' not found", metricKeyToSort, wsRequest.getMetricKeys()); return from(components) - .filter(new HasMeasure(measuresByComponentUuidAndMetric, metricToSort.get())) + .filter(new HasMeasure(measuresByComponentUuidAndMetric, metricToSort.get(), wsRequest)) .toList(); } @@ -418,21 +418,6 @@ public class ComponentTreeDataLoader { } } - private static class HasMeasure implements Predicate { - private final Table measuresByComponentUuidAndMetric; - private final MetricDto metric; - - private HasMeasure(Table measuresByComponentUuidAndMetric, MetricDto metric) { - this.measuresByComponentUuidAndMetric = measuresByComponentUuidAndMetric; - this.metric = metric; - } - - @Override - public boolean apply(@Nonnull ComponentDtoWithSnapshotId input) { - return measuresByComponentUuidAndMetric.contains(input.uuid(), metric); - } - } - private static class MatchMetricKey implements Predicate { private final String metricKeyToSort; diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/HasMeasure.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/HasMeasure.java new file mode 100644 index 00000000000..ed029069d00 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/HasMeasure.java @@ -0,0 +1,80 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.measure.ws; + +import com.google.common.base.Predicate; +import com.google.common.collect.Table; +import javax.annotation.Nonnull; +import org.sonar.db.component.ComponentDtoWithSnapshotId; +import org.sonar.db.measure.MeasureDto; +import org.sonar.db.metric.MetricDto; +import org.sonarqube.ws.client.measure.ComponentTreeWsRequest; + +class HasMeasure implements Predicate { + private final Predicate predicate; + + HasMeasure(Table measuresByComponentUuidAndMetric, MetricDto metric, ComponentTreeWsRequest request) { + Integer periodIndex = request.getMetricPeriodSort(); + this.predicate = periodIndex == null + ? new HasAbsoluteValue(measuresByComponentUuidAndMetric, metric) + : new HasValueOnPeriod(periodIndex, measuresByComponentUuidAndMetric, metric); + } + + @Override + public boolean apply(@Nonnull ComponentDtoWithSnapshotId input) { + return predicate.apply(input); + } + + private static class HasAbsoluteValue implements Predicate { + private final Table measuresByComponentUuidAndMetric; + private final MetricDto metric; + + private HasAbsoluteValue(Table measuresByComponentUuidAndMetric, MetricDto metric) { + this.measuresByComponentUuidAndMetric = measuresByComponentUuidAndMetric; + this.metric = metric; + } + + @Override + public boolean apply(@Nonnull ComponentDtoWithSnapshotId input) { + MeasureDto measure = measuresByComponentUuidAndMetric.get(input.uuid(), metric); + return measure != null && (measure.getValue() != null || measure.getData() != null); + } + } + + private static class HasValueOnPeriod implements Predicate { + private final int periodIndex; + private final Table measuresByComponentUuidAndMetric; + private final MetricDto metric; + + private HasValueOnPeriod(int periodIndex, Table measuresByComponentUuidAndMetric, MetricDto metric) { + this.periodIndex = periodIndex; + this.measuresByComponentUuidAndMetric = measuresByComponentUuidAndMetric; + this.metric = metric; + } + + @Override + public boolean apply(@Nonnull ComponentDtoWithSnapshotId input) { + MeasureDto measure = measuresByComponentUuidAndMetric.get(input.uuid(), metric); + return measure != null && measure.getVariation(periodIndex) != null; + } + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java index fd6553a4c68..ca4506a38cb 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java @@ -284,16 +284,18 @@ public class ComponentTreeActionTest { public void remove_components_without_measure_on_the_metric_sort() { ComponentDto projectDto = newProjectDto("project-uuid"); SnapshotDto projectSnapshot = componentDb.insertProjectAndSnapshot(projectDto); - componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-4"), projectSnapshot); + SnapshotDto fileSnapshot4 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-4"), projectSnapshot); SnapshotDto fileSnapshot3 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-3"), projectSnapshot); - SnapshotDto fileSnapshot1 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-1"), projectSnapshot); SnapshotDto fileSnapshot2 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-2"), projectSnapshot); + SnapshotDto fileSnapshot1 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-1"), projectSnapshot); MetricDto ncloc = newMetricDtoWithoutOptimization().setKey("ncloc").setValueType(ValueType.INT.name()).setDirection(1); dbClient.metricDao().insert(dbSession, ncloc); dbClient.measureDao().insert(dbSession, newMeasureDto(ncloc, fileSnapshot1.getId()).setValue(1.0d), newMeasureDto(ncloc, fileSnapshot2.getId()).setValue(2.0d), - newMeasureDto(ncloc, fileSnapshot3.getId()).setValue(3.0d)); + newMeasureDto(ncloc, fileSnapshot3.getId()).setValue(3.0d), + // measure on period 1 + newMeasureDto(ncloc, fileSnapshot4.getId()).setVariation(1, 4.0d)); db.commit(); ComponentTreeWsResponse response = call(ws.newRequest() @@ -334,6 +336,39 @@ public class ComponentTreeActionTest { assertThat(response.getComponentsList()).extracting("id").containsExactly("file-uuid-1", "file-uuid-2", "file-uuid-3"); } + @Test + public void remove_components_without_measure_on_the_metric_period_sort() { + ComponentDto projectDto = newProjectDto("project-uuid"); + SnapshotDto projectSnapshot = componentDb.insertProjectAndSnapshot(projectDto); + SnapshotDto fileSnapshot4 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-4"), projectSnapshot); + SnapshotDto fileSnapshot3 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-3"), projectSnapshot); + SnapshotDto fileSnapshot2 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-2"), projectSnapshot); + SnapshotDto fileSnapshot1 = componentDb.insertComponentAndSnapshot(newFileDto(projectDto, "file-uuid-1"), projectSnapshot); + MetricDto ncloc = newMetricDtoWithoutOptimization().setKey("new_ncloc").setValueType(ValueType.INT.name()).setDirection(1); + dbClient.metricDao().insert(dbSession, ncloc); + dbClient.measureDao().insert(dbSession, + newMeasureDto(ncloc, fileSnapshot1.getId()).setVariation(1, 1.0d), + newMeasureDto(ncloc, fileSnapshot2.getId()).setVariation(1, 2.0d), + newMeasureDto(ncloc, fileSnapshot3.getId()).setVariation(1, 3.0d), + // file 4 measure is on absolute value and period 2 + newMeasureDto(ncloc, fileSnapshot4.getId()) + .setValue(4.0d) + .setVariation(2, 4.0d)); + db.commit(); + + ComponentTreeWsResponse response = call(ws.newRequest() + .setParam(PARAM_BASE_COMPONENT_ID, "project-uuid") + .setParam(Param.SORT, METRIC_PERIOD_SORT + "," + NAME_SORT) + .setParam(PARAM_METRIC_SORT, "new_ncloc") + .setParam(PARAM_METRIC_KEYS, "new_ncloc") + .setParam(PARAM_METRIC_PERIOD_SORT, "1") + .setParam(PARAM_METRIC_SORT_FILTER, WITH_MEASURES_ONLY_METRIC_SORT_FILTER)); + + assertThat(response.getComponentsList()).extracting("id") + .containsExactly("file-uuid-1", "file-uuid-2", "file-uuid-3") + .doesNotContain("file-uuid-4"); + } + @Test public void load_developer_descendants() { ComponentDto developer = newDeveloper("developer").setUuid("developer-uuid"); -- 2.39.5