Procházet zdrojové kódy

SONAR-21455 Use a impact measure builder between all the components

tags/10.4.0.87286
Léo Geoffroy před 4 měsíci
rodič
revize
6d51e30181

+ 5
- 4
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/ImpactSumFormula.java Zobrazit soubor

@@ -21,6 +21,7 @@ package org.sonar.ce.task.projectanalysis.formula;

import java.util.Optional;
import org.sonar.ce.task.projectanalysis.measure.Measure;
import org.sonar.server.measure.ImpactMeasureBuilder;

import static java.util.Objects.requireNonNull;

@@ -56,14 +57,14 @@ public class ImpactSumFormula implements Formula<ImpactSumFormula.ImpactCounter>

private boolean initialized = false;
private boolean hasEmptyValue = false;
private final MeasureImpactBuilder measureImpactBuilder = new MeasureImpactBuilder();
private final ImpactMeasureBuilder measureImpactBuilder = ImpactMeasureBuilder.createEmpty();

@Override
public void aggregate(ImpactSumFormula.ImpactCounter counter) {
Optional<String> value = counter.getValue();
if (value.isPresent()) {
initialized = true;
measureImpactBuilder.add(value.get());
measureImpactBuilder.add(ImpactMeasureBuilder.fromString(value.get()));
} else {
hasEmptyValue = true;
}
@@ -75,7 +76,7 @@ public class ImpactSumFormula implements Formula<ImpactSumFormula.ImpactCounter>
String data = measureOptional.map(Measure::getData).orElse(null);
if (data != null) {
initialized = true;
measureImpactBuilder.add(data);
measureImpactBuilder.add(ImpactMeasureBuilder.fromString(data));
} else {
hasEmptyValue = true;
}
@@ -83,7 +84,7 @@ public class ImpactSumFormula implements Formula<ImpactSumFormula.ImpactCounter>

public Optional<String> getValue() {
if (initialized && !hasEmptyValue) {
return Optional.ofNullable(measureImpactBuilder.build());
return Optional.ofNullable(measureImpactBuilder.buildAsString());
}
return Optional.empty();
}

+ 0
- 42
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/formula/MeasureImpactBuilder.java Zobrazit soubor

@@ -1,42 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2024 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.ce.task.projectanalysis.formula;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;

public class MeasureImpactBuilder {
private static final Type GSON_MAP_TYPE = new TypeToken<Map<String, Integer>>() {
}.getType();
private static final Gson gson = new Gson();
private final Map<String, Integer> map = new LinkedHashMap<>();

public void add(String value) {
Map<String, Integer> impactMap = gson.fromJson(value, GSON_MAP_TYPE);
impactMap.forEach((key, val) -> map.merge(key, val, Integer::sum));
}

public String build() {
return gson.toJson(map);
}
}

+ 4
- 11
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueCounter.java Zobrazit soubor

@@ -23,7 +23,6 @@ import com.google.common.collect.EnumMultiset;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multiset;
import com.google.gson.Gson;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
@@ -37,6 +36,7 @@ import org.sonar.ce.task.projectanalysis.measure.MeasureRepository;
import org.sonar.ce.task.projectanalysis.metric.Metric;
import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.server.measure.ImpactMeasureBuilder;

import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
import static org.sonar.api.issue.Issue.STATUS_OPEN;
@@ -126,8 +126,6 @@ public class IssueCounter extends IssueVisitor {
.put(SECURITY_HOTSPOT, NEW_SECURITY_HOTSPOTS_KEY)
.build();

private static final Gson gson = new Gson();

private final MetricRepository metricRepository;
private final MeasureRepository measureRepository;
private final NewIssueClassifier newIssueClassifier;
@@ -191,7 +189,7 @@ public class IssueCounter extends IssueVisitor {

private void addMeasuresByImpact(Component component) {
for (Map.Entry<String, Map<String, Long>> impactEntry : currentCounters.counter().impactsBag.entrySet()) {
String json = gson.toJson(impactEntry.getValue());
String json = ImpactMeasureBuilder.fromMap(impactEntry.getValue()).buildAsString();
addMeasure(component, IMPACT_TO_METRIC_KEY.get(impactEntry.getKey()), json);
}
}
@@ -267,12 +265,7 @@ public class IssueCounter extends IssueVisitor {

private void initImpactsBag() {
for (SoftwareQuality quality : SoftwareQuality.values()) {
Map<String, Long> severityMap = new HashMap<>();
for (Severity severity : Severity.values()) {
severityMap.put(severity.name(), 0L);
}
severityMap.put("total", 0L);
impactsBag.put(quality.name(), severityMap);
impactsBag.put(quality.name(), ImpactMeasureBuilder.createEmpty().buildAsMap());
}
}

@@ -336,7 +329,7 @@ public class IssueCounter extends IssueVisitor {
for (Map.Entry<SoftwareQuality, Severity> impact : issue.impacts().entrySet()) {
impactsBag.compute(impact.getKey().name(), (key, value) -> {
value.compute(impact.getValue().name(), (severity, count) -> count == null ? 1 : count + 1);
value.compute("total", (total, count) -> count == null ? 1 : count + 1);
value.compute(ImpactMeasureBuilder.TOTAL_KEY, (total, count) -> count == null ? 1 : count + 1);
return value;
});
}

+ 7
- 2
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/ImpactSumFormulaTest.java Zobrazit soubor

@@ -20,7 +20,7 @@
package org.sonar.ce.task.projectanalysis.formula;

import com.google.gson.Gson;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.Optional;
import javax.annotation.Nullable;
import org.junit.Test;
@@ -131,7 +131,12 @@ public class ImpactSumFormulaTest {


public String newImpactJson(Integer total, Integer high, Integer medium, Integer low) {
return gson.toJson(Map.of("total", total, Severity.HIGH.name(), high, Severity.MEDIUM.name(), medium, Severity.LOW.name(), low));
LinkedHashMap<Object, Object> map = new LinkedHashMap<>();
map.put(Severity.LOW.name(), low);
map.put(Severity.MEDIUM.name(), medium);
map.put(Severity.HIGH.name(), high);
map.put("total", total);
return gson.toJson(map);
}

private void addMeasure(String metricKey, @Nullable String value) {

+ 0
- 57
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/formula/MeasureImpactBuilderTest.java Zobrazit soubor

@@ -1,57 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2024 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.ce.task.projectanalysis.formula;

import com.google.gson.Gson;
import java.util.Map;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.sonar.api.issue.impact.Severity;


public class MeasureImpactBuilderTest {

Gson gson = new Gson();

@Test
public void add_shouldAddExpectedInitialValues() {
MeasureImpactBuilder measureImpactBuilder = new MeasureImpactBuilder();
Assertions.assertThat(measureImpactBuilder.build()).isEqualTo("{}");

measureImpactBuilder = new MeasureImpactBuilder();
Map<String, Integer> map = Map.of("total", 3, Severity.HIGH.name(), 2, Severity.MEDIUM.name(), 1, Severity.LOW.name(), 4);
measureImpactBuilder.add(gson.toJson(map));
Assertions.assertThat(measureImpactBuilder.build()).isEqualTo(gson.toJson(map));
}

@Test
public void add_shouldMergeValuesFromDifferentMaps() {

MeasureImpactBuilder measureImpactBuilder = new MeasureImpactBuilder();
Map<String, Integer> map = Map.of("total", 3, Severity.HIGH.name(), 2, Severity.MEDIUM.name(), 1, Severity.LOW.name(), 4);
measureImpactBuilder.add(gson.toJson(map));

Map<String, Integer> map2 = Map.of("total", 6, Severity.HIGH.name(), 4, Severity.MEDIUM.name(), 2, Severity.LOW.name(), 1);
measureImpactBuilder.add(gson.toJson(map2));

Assertions.assertThat(measureImpactBuilder.build()).isEqualTo(gson.toJson(Map.of("total", 9, Severity.HIGH.name(), 6, Severity.MEDIUM.name(), 3, Severity.LOW.name(), 5)));
}

}

+ 15
- 7
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java Zobrazit soubor

@@ -20,12 +20,11 @@
package org.sonar.ce.task.projectanalysis.issue;

import com.google.gson.Gson;
import java.lang.constant.Constable;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.assertj.core.data.MapEntry;
import org.junit.Rule;
@@ -42,6 +41,7 @@ import org.sonar.ce.task.projectanalysis.measure.MeasureRepositoryRule;
import org.sonar.ce.task.projectanalysis.metric.MetricRepositoryRule;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.measure.ImpactMeasureBuilder;

import static java.util.Arrays.stream;
import static org.assertj.core.api.Assertions.assertThat;
@@ -360,14 +360,22 @@ public class IssueCounterTest {

Set<Map.Entry<String, Measure>> entries = measureRepository.getRawMeasures(FILE1).entrySet();

assertSoftwareQualityMeasures(SoftwareQuality.MAINTAINABILITY, Map.of(HIGH, 2, MEDIUM, 2, LOW, 0, "total", 4), entries);
assertSoftwareQualityMeasures(SoftwareQuality.SECURITY, Map.of(HIGH, 1, MEDIUM, 1, LOW, 0, "total", 2), entries);
assertSoftwareQualityMeasures(SoftwareQuality.RELIABILITY, Map.of(HIGH, 0, MEDIUM, 0, LOW, 0, "total", 0), entries);
assertSoftwareQualityMeasures(SoftwareQuality.MAINTAINABILITY, getImpactMeasure(4, 2, 2, 0), entries);
assertSoftwareQualityMeasures(SoftwareQuality.SECURITY, getImpactMeasure(2, 1, 1, 0), entries);
assertSoftwareQualityMeasures(SoftwareQuality.RELIABILITY, getImpactMeasure(0, 0, 0, 0), entries);
}

private void assertSoftwareQualityMeasures(SoftwareQuality softwareQuality, Map<? extends Constable, Integer> expectedRaw,
private static Map<String, Long> getImpactMeasure(long total, long high, long medium, long low) {
Map<String, Long> map = new LinkedHashMap<>();
map.put(LOW.name(), low);
map.put(MEDIUM.name(), medium);
map.put(HIGH.name(), high);
map.put(ImpactMeasureBuilder.TOTAL_KEY, total);
return map;
}

private void assertSoftwareQualityMeasures(SoftwareQuality softwareQuality, Map<? extends String, Long> expectedMap,
Set<Map.Entry<String, Measure>> actualRaw) {
Map<String, Long> expectedMap = expectedRaw.entrySet().stream().collect(Collectors.toMap(k -> k.getKey().toString(), v -> v.getValue().longValue()));

Map.Entry<String, Measure> softwareQualityMap = actualRaw.stream()
.filter(e -> e.getKey().equals(IMPACT_TO_METRIC_KEY.get(softwareQuality.name())))

+ 102
- 0
server/sonar-server-common/src/main/java/org/sonar/server/measure/ImpactMeasureBuilder.java Zobrazit soubor

@@ -0,0 +1,102 @@
/*
* SonarQube
* Copyright (C) 2009-2024 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.server.measure;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import org.sonar.api.issue.impact.Severity;

import static org.sonar.api.utils.Preconditions.checkArgument;

/**
* Builder class to help build measures based on impacts with payload such as @{link {@link org.sonar.api.measures.CoreMetrics#RELIABILITY_ISSUES}}.
*/
public class ImpactMeasureBuilder {

private static final Gson GSON = new GsonBuilder().create();
private static final Type GSON_MAP_TYPE = new TypeToken<Map<String, Long>>() {
}.getType();
public static final String TOTAL_KEY = "total";

private final Map<String, Long> map;

private ImpactMeasureBuilder(Map<String, Long> map) {
this.map = new LinkedHashMap<>(map);
}

public static ImpactMeasureBuilder createEmpty() {
Map<String, Long> severityMap = new LinkedHashMap<>();
for (Severity severity : Severity.values()) {
severityMap.put(severity.name(), 0L);
}
severityMap.put(TOTAL_KEY, 0L);
return new ImpactMeasureBuilder(severityMap);
}

public static ImpactMeasureBuilder newInstance() {
return new ImpactMeasureBuilder(new LinkedHashMap<>());
}

public static ImpactMeasureBuilder fromMap(Map<String, Long> map) {
checkImpactMap(map);
return new ImpactMeasureBuilder(map);
}

private static void checkImpactMap(Map<String, Long> map) {
checkArgument(map.containsKey(TOTAL_KEY), "Map must contain a total key");
Arrays.stream(Severity.values()).forEach(severity -> checkArgument(map.containsKey(severity.name()), "Map must contain a key for severity " + severity.name()));
}

public static ImpactMeasureBuilder fromString(String value) {
Map<String, Long> impactMap = GSON.fromJson(value, GSON_MAP_TYPE);
checkImpactMap(impactMap);
return new ImpactMeasureBuilder(impactMap);
}

public ImpactMeasureBuilder setSeverity(Severity severity, long value) {
map.put(severity.name(), value);
return this;
}

public ImpactMeasureBuilder setTotal(long value) {
map.put(TOTAL_KEY, value);
return this;
}

public ImpactMeasureBuilder add(ImpactMeasureBuilder other) {
other.buildAsMap().forEach((key, val) -> map.merge(key, val, Long::sum));
return this;
}

public String buildAsString() {
checkImpactMap(map);
return GSON.toJson(map);
}

public Map<String, Long> buildAsMap() {
checkImpactMap(map);
return map;
}
}

+ 129
- 0
server/sonar-server-common/src/test/java/org/sonar/server/measure/ImpactMeasureBuilderTest.java Zobrazit soubor

@@ -0,0 +1,129 @@
/*
* SonarQube
* Copyright (C) 2009-2024 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.server.measure;

import java.util.Map;
import org.junit.Test;
import org.sonar.api.issue.impact.Severity;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

public class ImpactMeasureBuilderTest {

@Test
public void createEmptyMeasure_shouldReturnMeasureWithAllFields() {
ImpactMeasureBuilder builder = ImpactMeasureBuilder.createEmpty();
assertThat(builder.buildAsMap())
.containsAllEntriesOf(getImpactMap(0L, 0L, 0L, 0L));
}

private static Map<String, Long> getImpactMap(Long total, Long high, Long medium, Long low) {
return Map.of("total", total, Severity.HIGH.name(), high, Severity.MEDIUM.name(), medium, Severity.LOW.name(), low);
}

@Test
public void fromMap_shouldInitializeCorrectlyTheBuilder() {
Map<String, Long> map = getImpactMap(6L, 3L, 2L, 1L);
ImpactMeasureBuilder builder = ImpactMeasureBuilder.fromMap(map);
assertThat(builder.buildAsMap())
.isEqualTo(map);
}

@Test
public void fromMap_whenMissingField_shouldThrowException() {
Map<String, Long> map = Map.of();
assertThatThrownBy(() -> ImpactMeasureBuilder.fromMap(map))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Map must contain a total key");
}

@Test
public void toString_shouldInitializeCorrectlyTheBuilder() {
ImpactMeasureBuilder builder = ImpactMeasureBuilder.fromString("""
{
total: 6,
HIGH: 3,
MEDIUM: 2,
LOW: 1
}
""");
assertThat(builder.buildAsMap())
.isEqualTo(getImpactMap(6L, 3L, 2L, 1L));
}

@Test
public void buildAsMap_whenIsEmpty_shouldThrowException() {
ImpactMeasureBuilder impactMeasureBuilder = ImpactMeasureBuilder.newInstance();
assertThatThrownBy(impactMeasureBuilder::buildAsMap)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Map must contain a total key");
}

@Test
public void buildAsMap_whenMissingSeverity_shouldThrowException() {
ImpactMeasureBuilder impactMeasureBuilder = ImpactMeasureBuilder.newInstance()
.setTotal(1L)
.setSeverity(Severity.HIGH, 1L)
.setSeverity(Severity.MEDIUM, 1L);
assertThatThrownBy(impactMeasureBuilder::buildAsMap)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Map must contain a key for severity LOW");
}

@Test
public void buildAsString_whenMissingSeverity_shouldThrowException() {
ImpactMeasureBuilder impactMeasureBuilder = ImpactMeasureBuilder.newInstance()
.setTotal(1L)
.setSeverity(Severity.HIGH, 1L)
.setSeverity(Severity.MEDIUM, 1L);
assertThatThrownBy(impactMeasureBuilder::buildAsString)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Map must contain a key for severity LOW");
}

@Test
public void setSeverity_shouldInitializeSeverityValues() {
ImpactMeasureBuilder builder = ImpactMeasureBuilder.newInstance()
.setSeverity(Severity.HIGH, 3L)
.setSeverity(Severity.MEDIUM, 2L)
.setSeverity(Severity.LOW, 1L)
.setTotal(6L);
assertThat(builder.buildAsMap())
.isEqualTo(getImpactMap(6L, 3L, 2L, 1L));
}

@Test
public void add_shouldSumImpactsAndTotal() {
ImpactMeasureBuilder builder = ImpactMeasureBuilder.fromMap(getImpactMap(6L, 3L, 2L, 1L))
.add(ImpactMeasureBuilder.newInstance().setTotal(6L).setSeverity(Severity.HIGH, 3L).setSeverity(Severity.MEDIUM, 2L).setSeverity(Severity.LOW, 1L));
assertThat(builder.buildAsMap())
.isEqualTo(getImpactMap(12L, 6L, 4L, 2L));
}

@Test
public void add_whenOtherMapHasMissingField_shouldThrowException() {
ImpactMeasureBuilder impactMeasureBuilder = ImpactMeasureBuilder.newInstance();
assertThatThrownBy(() -> impactMeasureBuilder.add(ImpactMeasureBuilder.newInstance()))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Map must contain a total key");
}

}

+ 7
- 11
server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/IssueCounter.java Zobrazit soubor

@@ -19,8 +19,6 @@
*/
package org.sonar.server.measure.live;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.Collection;
import java.util.EnumMap;
import java.util.HashMap;
@@ -34,6 +32,7 @@ import org.sonar.api.rules.RuleType;
import org.sonar.db.issue.IssueGroupDto;
import org.sonar.db.issue.IssueImpactGroupDto;
import org.sonar.db.rule.SeverityUtil;
import org.sonar.server.measure.ImpactMeasureBuilder;

import static org.sonar.api.rule.Severity.INFO;
import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT;
@@ -50,7 +49,6 @@ class IssueCounter {
private final Count unresolved = new Count();
private final Count highImpactAccepted = new Count();
private final Map<SoftwareQuality, Map<Severity, Count>> bySoftwareQualityAndSeverity = new EnumMap<>(SoftwareQuality.class);
private final Gson gson = new GsonBuilder().create();

IssueCounter(Collection<IssueGroupDto> groups, Collection<IssueImpactGroupDto> impactGroups) {
for (IssueGroupDto group : groups) {
@@ -172,20 +170,18 @@ class IssueCounter {
public String getBySoftwareQuality(SoftwareQuality softwareQuality) {
Map<Severity, Count> severityToCount = bySoftwareQualityAndSeverity.get(softwareQuality);

Map<String, Long> impactMap = new HashMap<>();
ImpactMeasureBuilder impactMeasureBuilder;
if (severityToCount != null) {
impactMap.put("total", severityToCount.values().stream().mapToLong(count -> count.absolute).sum());
impactMeasureBuilder = ImpactMeasureBuilder.newInstance();
for (Severity severity : Severity.values()) {
impactMap.put(severity.name(), Optional.ofNullable(severityToCount.get(severity)).map(count -> count.absolute).orElse(0L));
impactMeasureBuilder = impactMeasureBuilder.setSeverity(severity, Optional.ofNullable(severityToCount.get(severity)).map(count -> count.absolute).orElse(0L));
}
impactMeasureBuilder = impactMeasureBuilder.setTotal(severityToCount.values().stream().mapToLong(count -> count.absolute).sum());
} else {
impactMap.put("total", 0L);
for (Severity severity : Severity.values()) {
impactMap.put(severity.name(), 0L);
}
impactMeasureBuilder = ImpactMeasureBuilder.createEmpty();
}

return gson.toJson(impactMap);
return impactMeasureBuilder.buildAsString();
}

private static class Count {

+ 7
- 26
server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java Zobrazit soubor

@@ -19,24 +19,18 @@
*/
package org.sonar.server.measure.live;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.impact.SoftwareQuality;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RuleType;
import org.sonar.server.measure.ImpactMeasureBuilder;
import org.sonar.server.measure.Rating;

import static java.util.Arrays.asList;
@@ -255,9 +249,6 @@ public class MeasureUpdateFormulaFactoryImpl implements MeasureUpdateFormulaFact

private static final Set<Metric> FORMULA_METRICS = MeasureUpdateFormulaFactory.extractMetrics(FORMULAS);

private static final Gson GSON = new GsonBuilder().create();
private static final Type MAP_TYPE = new TypeToken<Map<String, Long>>() {}.getType();

private static double debtDensity(MeasureUpdateFormula.Context context) {
double debt = Math.max(context.getValue(CoreMetrics.TECHNICAL_DEBT).orElse(0.0D), 0.0D);
Optional<Double> devCost = context.getText(CoreMetrics.DEVELOPMENT_COST).map(Double::parseDouble);
@@ -305,22 +296,12 @@ public class MeasureUpdateFormulaFactoryImpl implements MeasureUpdateFormulaFact
private static class ImpactAddChildren implements BiConsumer<MeasureUpdateFormula.Context, MeasureUpdateFormula> {
@Override
public void accept(MeasureUpdateFormula.Context context, MeasureUpdateFormula formula) {
List<Map<String, Long>> measures = context.getChildrenTextValues().stream()
.map(ImpactAddChildren::toMap)
.collect(Collectors.toList());
context.getText(formula.getMetric()).ifPresent(value -> measures.add(toMap(value)));

Map<String, Long> newValue = new HashMap<>();
newValue.put("total", measures.stream().mapToLong(map -> map.get("total")).sum());
for (org.sonar.api.issue.impact.Severity severity : org.sonar.api.issue.impact.Severity.values()) {
newValue.put(severity.name(), measures.stream().mapToLong(map -> map.get(severity.name())).sum());
}

context.setValue(GSON.toJson(newValue));
}

private static Map<String, Long> toMap(String value) {
return GSON.fromJson(value, MAP_TYPE);
ImpactMeasureBuilder impactMeasureBuilder = ImpactMeasureBuilder.createEmpty();
context.getChildrenTextValues().stream()
.map(ImpactMeasureBuilder::fromString)
.forEach(impactMeasureBuilder::add);
context.getText(formula.getMetric()).ifPresent(value -> impactMeasureBuilder.add(ImpactMeasureBuilder.fromString(value)));
context.setValue(impactMeasureBuilder.buildAsString());
}
}


Načítá se…
Zrušit
Uložit