3 * Copyright (C) 2009-2023 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.MeasureValueFormatter.formatMeasureValue;
40 class SearchHistoryResponseFactory {
41 private final SearchHistoryResult result;
42 private final HistoryMeasure.Builder measure;
43 private final HistoryValue.Builder value;
45 SearchHistoryResponseFactory(SearchHistoryResult result) {
47 this.measure = HistoryMeasure.newBuilder();
48 this.value = HistoryValue.newBuilder();
51 public SearchHistoryResponse apply() {
52 return Optional.of(SearchHistoryResponse.newBuilder())
55 .map(SearchHistoryResponse.Builder::build)
59 private UnaryOperator<SearchHistoryResponse.Builder> addPaging() {
60 return response -> response.setPaging(result.getPaging());
63 private UnaryOperator<SearchHistoryResponse.Builder> addMeasures() {
64 Map<String, MetricDto> metricsByUuid = result.getMetrics().stream().collect(Collectors.toMap(MetricDto::getUuid, Function.identity()));
65 Map<String, SnapshotDto> analysesByUuid = result.getAnalyses().stream().collect(Collectors.toMap(SnapshotDto::getUuid, Function.identity()));
66 Table<MetricDto, SnapshotDto, MeasureDto> measuresByMetricByAnalysis = HashBasedTable.create(result.getMetrics().size(), result.getAnalyses().size());
67 result.getMeasures().forEach(m -> measuresByMetricByAnalysis.put(metricsByUuid.get(m.getMetricUuid()), analysesByUuid.get(m.getAnalysisUuid()), m));
70 result.getMetrics().stream()
73 .map(metric -> addValues(measuresByMetricByAnalysis.row(metric)).apply(metric))
74 .forEach(metric -> response.addMeasures(measure));
80 private UnaryOperator<MetricDto> addMetric() {
82 measure.setMetric(metric.getKey());
87 private UnaryOperator<MetricDto> addValues(Map<SnapshotDto, MeasureDto> measuresByAnalysis) {
89 result.getAnalyses().stream()
92 .map(analysis -> addValue(analysis, metric, measuresByAnalysis.get(analysis)))
93 .forEach(analysis -> measure.addHistory(value));
99 private UnaryOperator<SnapshotDto> addDate() {
101 value.setDate(formatDateTime(analysis.getCreatedAt()));
106 private SnapshotDto addValue(SnapshotDto analysis, MetricDto dbMetric, @Nullable MeasureDto dbMeasure) {
107 if (dbMeasure != null) {
108 String measureValue = formatMeasureValue(dbMeasure, dbMetric);
109 if (measureValue != null) {
110 value.setValue(measureValue);
117 private UnaryOperator<MetricDto> clearMetric() {
124 private UnaryOperator<SnapshotDto> clearValue() {