aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsMapper.java
blob: c5dfe9fbcad07e5aaf6861f9fe9ef2ffcd8703c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * SonarQube
 * Copyright (C) 2009-2025 SonarSource SA
 * mailto:info 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.telemetry.metrics;

import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import org.sonar.telemetry.core.Granularity;
import org.sonar.telemetry.core.TelemetryDataProvider;
import org.sonar.telemetry.core.schema.InstallationMetric;
import org.sonar.telemetry.core.schema.LanguageMetric;
import org.sonar.telemetry.core.schema.Metric;
import org.sonar.telemetry.core.schema.ProjectMetric;
import org.sonar.telemetry.core.schema.UserMetric;

public class TelemetryMetricsMapper {

  private TelemetryMetricsMapper() {
  }

  public static Set<Metric> mapFromDataProvider(TelemetryDataProvider<?> provider) {
    switch (provider.getDimension()) {
      case INSTALLATION -> {
        return mapInstallationMetric(provider);
      }
      case PROJECT -> {
        return mapProjectMetric(provider);
      }
      case USER -> {
        return mapUserMetric(provider);
      }
      case LANGUAGE -> {
        return mapLanguageMetric(provider);
      }
      default -> throw new IllegalArgumentException("Dimension: " + provider.getDimension() + " not yet implemented.");
    }
  }

  private static Set<Metric> mapInstallationMetric(TelemetryDataProvider<?> provider) {
    // Case 1: the provider has implemented getValues() and it is non‐empty
    var multiValues = provider.getValues();
    if (!multiValues.isEmpty()) {
      return multiValues.entrySet().stream()
        .map(entry -> new InstallationMetric(
          provider.getMetricKey() + "." + entry.getKey(),
          entry.getValue(),
          provider.getType(),
          provider.getGranularity()))
        .collect(Collectors.toSet());
    }

    // Case 2: the provider has implemented getValue() and it is non‐empty
    var singleValue = provider.getValue();
    if (singleValue.isPresent()) {
      return Collections.singleton(new InstallationMetric(
        provider.getMetricKey(),
        singleValue.orElse(null),
        provider.getType(),
        provider.getGranularity()));
    }

    // Case 3: the provider has not implemented getValue() or getValues(), or both are empty
    if (provider.getGranularity() == Granularity.ADHOC) {
      return Collections.emptySet();
    } else {
      // It's not clear whether we actually want to send a null metric in this case, but we do for now to be consistent with the previous implementation.
      return Collections.singleton(new InstallationMetric(
        provider.getMetricKey(),
        null,
        provider.getType(),
        provider.getGranularity()));
    }
  }

  // Note: Dimension.USER does not currently support getValue(). But we just silently ignore it if a provider tries to use it.
  private static Set<Metric> mapUserMetric(TelemetryDataProvider<?> provider) {
    return provider.getValues().entrySet().stream()
      .map(entry -> new UserMetric(
        provider.getMetricKey(),
        entry.getValue(),
        entry.getKey(),
        provider.getType(),
        provider.getGranularity()))
      .collect(Collectors.toSet());
  }

  // Note: Dimension.PROJECT does not currently support getValue(). But we just silently ignore it if a provider tries to use it.
  private static Set<Metric> mapProjectMetric(TelemetryDataProvider<?> provider) {
    return provider.getValues().entrySet().stream()
      .map(entry -> new ProjectMetric(
        provider.getMetricKey(),
        entry.getValue(),
        entry.getKey(),
        provider.getType(),
        provider.getGranularity()))
      .collect(Collectors.toSet());
  }

  // Note: Dimension.LANGUAGE does not currently support getValue(). But we just silently ignore it if a provider tries to use it.
  private static Set<Metric> mapLanguageMetric(TelemetryDataProvider<?> provider) {
    return provider.getValues().entrySet().stream()
      .map(entry -> new LanguageMetric(
        provider.getMetricKey(),
        entry.getValue(),
        entry.getKey(),
        provider.getType(),
        provider.getGranularity()))
      .collect(Collectors.toSet());
  }
}