]> source.dussan.org Git - sonarqube.git/blob
a5764f6459e40e0cd568e673ea609f9ef0a24e96
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2023 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
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.
10  *
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.
15  *
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.
19  */
20 package org.sonar.server.measure.ws;
21
22 import com.google.common.collect.HashBasedTable;
23 import com.google.common.collect.Table;
24 import java.util.Map;
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;
36
37 import static org.sonar.api.utils.DateUtils.formatDateTime;
38 import static org.sonar.server.measure.ws.MeasureValueFormatter.formatMeasureValue;
39
40 class SearchHistoryResponseFactory {
41   private final SearchHistoryResult result;
42   private final HistoryMeasure.Builder measure;
43   private final HistoryValue.Builder value;
44
45   SearchHistoryResponseFactory(SearchHistoryResult result) {
46     this.result = result;
47     this.measure = HistoryMeasure.newBuilder();
48     this.value = HistoryValue.newBuilder();
49   }
50
51   public SearchHistoryResponse apply() {
52     return Optional.of(SearchHistoryResponse.newBuilder())
53       .map(addPaging())
54       .map(addMeasures())
55       .map(SearchHistoryResponse.Builder::build)
56       .orElseThrow();
57   }
58
59   private UnaryOperator<SearchHistoryResponse.Builder> addPaging() {
60     return response -> response.setPaging(result.getPaging());
61   }
62
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));
68
69     return response -> {
70       result.getMetrics().stream()
71         .map(clearMetric())
72         .map(addMetric())
73         .map(metric -> addValues(measuresByMetricByAnalysis.row(metric)).apply(metric))
74         .forEach(metric -> response.addMeasures(measure));
75
76       return response;
77     };
78   }
79
80   private UnaryOperator<MetricDto> addMetric() {
81     return metric -> {
82       measure.setMetric(metric.getKey());
83       return metric;
84     };
85   }
86
87   private UnaryOperator<MetricDto> addValues(Map<SnapshotDto, MeasureDto> measuresByAnalysis) {
88     return metric -> {
89       result.getAnalyses().stream()
90         .map(clearValue())
91         .map(addDate())
92         .map(analysis -> addValue(analysis, metric, measuresByAnalysis.get(analysis)))
93         .forEach(analysis -> measure.addHistory(value));
94
95       return metric;
96     };
97   }
98
99   private UnaryOperator<SnapshotDto> addDate() {
100     return analysis -> {
101       value.setDate(formatDateTime(analysis.getCreatedAt()));
102       return analysis;
103     };
104   }
105
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);
111       }
112     }
113
114     return analysis;
115   }
116
117   private UnaryOperator<MetricDto> clearMetric() {
118     return metric -> {
119       measure.clear();
120       return metric;
121     };
122   }
123
124   private UnaryOperator<SnapshotDto> clearValue() {
125     return analysis -> {
126       value.clear();
127       return analysis;
128     };
129   }
130 }