3 * Copyright (C) 2009-2024 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.server.measure.ws;
22 import com.google.common.collect.HashBasedTable;
23 import com.google.common.collect.Table;
25 import java.util.Optional;
26 import java.util.function.Function;
27 import java.util.function.UnaryOperator;
28 import java.util.stream.Collectors;
29 import javax.annotation.Nullable;
30 import org.sonar.db.component.SnapshotDto;
31 import org.sonar.db.measure.MeasureDto;
32 import org.sonar.db.metric.MetricDto;
33 import org.sonarqube.ws.Measures.SearchHistoryResponse;
34 import org.sonarqube.ws.Measures.SearchHistoryResponse.HistoryMeasure;
35 import org.sonarqube.ws.Measures.SearchHistoryResponse.HistoryValue;
37 import static org.sonar.api.utils.DateUtils.formatDateTime;
38 import static org.sonar.server.measure.ws.ComponentResponseCommon.addMetricToSearchHistoryResponseIncludingRenamedMetric;
39 import static org.sonar.server.measure.ws.MeasureValueFormatter.formatMeasureValue;
41 class SearchHistoryResponseFactory {
42 private final SearchHistoryResult result;
43 private final HistoryMeasure.Builder measure;
44 private final HistoryValue.Builder value;
46 SearchHistoryResponseFactory(SearchHistoryResult result) {
48 this.measure = HistoryMeasure.newBuilder();
49 this.value = HistoryValue.newBuilder();
52 public SearchHistoryResponse apply() {
53 return Optional.of(SearchHistoryResponse.newBuilder())
56 .map(SearchHistoryResponse.Builder::build)
60 private UnaryOperator<SearchHistoryResponse.Builder> addPaging() {
61 return response -> response.setPaging(result.getPaging());
64 private UnaryOperator<SearchHistoryResponse.Builder> addMeasures() {
65 Map<String, MetricDto> metricsByUuid = result.getMetrics().stream().collect(Collectors.toMap(MetricDto::getUuid, Function.identity()));
66 Map<String, SnapshotDto> analysesByUuid = result.getAnalyses().stream().collect(Collectors.toMap(SnapshotDto::getUuid, Function.identity()));
67 Table<MetricDto, SnapshotDto, MeasureDto> measuresByMetricByAnalysis = HashBasedTable.create(result.getMetrics().size(), result.getAnalyses().size());
68 result.getMeasures().forEach(m -> measuresByMetricByAnalysis.put(metricsByUuid.get(m.getMetricUuid()), analysesByUuid.get(m.getAnalysisUuid()), m));
71 for (MetricDto metric : result.getMetrics()) {
72 measure.setMetric(metric.getKey());
73 addValues(measuresByMetricByAnalysis.row(metric)).apply(metric);
74 addMetricToSearchHistoryResponseIncludingRenamedMetric(response, result.getRequestedMetrics(), measure);
82 private UnaryOperator<MetricDto> addValues(Map<SnapshotDto, MeasureDto> measuresByAnalysis) {
84 result.getAnalyses().stream()
87 .map(analysis -> addValue(analysis, metric, measuresByAnalysis.get(analysis)))
88 .forEach(analysis -> measure.addHistory(value));
94 private UnaryOperator<SnapshotDto> addDate() {
96 value.setDate(formatDateTime(analysis.getCreatedAt()));
101 private SnapshotDto addValue(SnapshotDto analysis, MetricDto dbMetric, @Nullable MeasureDto dbMeasure) {
102 if (dbMeasure != null) {
103 String measureValue = formatMeasureValue(dbMeasure, dbMetric);
104 if (measureValue != null) {
105 value.setValue(measureValue);
112 private UnaryOperator<SnapshotDto> clearValue() {