diff options
9 files changed, 74 insertions, 44 deletions
diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DefaultResourceTypes.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DefaultResourceTypes.java index e521d627380..2386030a5b9 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DefaultResourceTypes.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/DefaultResourceTypes.java @@ -31,24 +31,27 @@ import org.sonar.api.resources.ResourceTypeTree; public final class DefaultResourceTypes extends ExtensionProvider implements BatchExtension, ServerExtension { private static final String SUPPORTS_MEASURE_FILTERS = "supportsMeasureFilters"; + private static final String CONFIGURABLE = "configurable";; + private static final String UPDATABLE_KEY = "updatable_key"; @Override public ResourceTypeTree provide() { + return ResourceTypeTree.builder() .addType(ResourceType.builder(Qualifiers.PROJECT) .setProperty("deletable", true) .setProperty("supportsGlobalDashboards", true) .setProperty("modifiable_history", true) .setProperty("hasRolePolicy", true) - .setProperty("updatable_key", true) + .setProperty(UPDATABLE_KEY, true) .setProperty(SUPPORTS_MEASURE_FILTERS, true) .setProperty("comparable", true) - .setProperty("configurable", true) + .setProperty(CONFIGURABLE, true) .build()) .addType(ResourceType.builder(Qualifiers.MODULE) - .setProperty("updatable_key", true) + .setProperty(UPDATABLE_KEY, true) .setProperty(SUPPORTS_MEASURE_FILTERS, true) - .setProperty("configurable", true) + .setProperty(CONFIGURABLE, true) .build()) .addType(ResourceType.builder(Qualifiers.DIRECTORY) .setProperty(SUPPORTS_MEASURE_FILTERS, true) diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/ProjectTimeMachineDashboard.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/ProjectTimeMachineDashboard.java index 92c3772b82f..82ea4532bf1 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/ProjectTimeMachineDashboard.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/dashboards/ProjectTimeMachineDashboard.java @@ -38,6 +38,7 @@ public final class ProjectTimeMachineDashboard extends DashboardTemplate { private static final String METRIC5 = "metric5"; private static final String METRIC6 = "metric6"; private static final String METRIC7 = "metric7"; + private static final String COVERAGE = "coverage"; @Override public String getName() { @@ -57,7 +58,7 @@ public final class ProjectTimeMachineDashboard extends DashboardTemplate { Widget timelineWidget = dashboard.addWidget("timeline", 1); timelineWidget.setProperty(METRIC1, "complexity"); timelineWidget.setProperty(METRIC2, "violations_density"); - timelineWidget.setProperty(METRIC3, "coverage"); + timelineWidget.setProperty(METRIC3, COVERAGE); Widget sizeTimeMachineWidget = addTimeMachineWidgetOnFirstColumn(dashboard); sizeTimeMachineWidget.setProperty(METRIC1, "ncloc"); @@ -99,7 +100,7 @@ public final class ProjectTimeMachineDashboard extends DashboardTemplate { complexityTimeMachineWidget.setProperty(METRIC4, "file_complexity"); Widget testsTimeMachineWidget = addTimeMachineWidgetOnSecondColumn(dashboard); - testsTimeMachineWidget.setProperty(METRIC1, "coverage"); + testsTimeMachineWidget.setProperty(METRIC1, COVERAGE); testsTimeMachineWidget.setProperty(METRIC2, "line_coverage"); testsTimeMachineWidget.setProperty(METRIC3, "branch_coverage"); testsTimeMachineWidget.setProperty(METRIC4, "test_success_density"); diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CheckAlertThresholds.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CheckAlertThresholds.java index 2da8eead044..6df77203f72 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CheckAlertThresholds.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/CheckAlertThresholds.java @@ -40,6 +40,7 @@ import java.util.Locale; public class CheckAlertThresholds implements Decorator { private static final String VARIATION_METRIC_PREFIX = "new_"; + private static final String VARIATION = "variation"; private final Snapshot snapshot; private final RulesProfile profile; @@ -139,7 +140,7 @@ public class CheckAlertThresholds implements Decorator { stringBuilder.append(metric); if (alertPeriod != null && !alert.getMetric().getKey().startsWith(VARIATION_METRIC_PREFIX)) { - String variation = i18n.message(getLocale(), "variation", "variation").toLowerCase(); + String variation = i18n.message(getLocale(), VARIATION, VARIATION).toLowerCase(); stringBuilder.append(" ").append(variation); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java index 4d4a47d6df2..5efdabe3da9 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/DefaultIndex.java @@ -30,17 +30,8 @@ import org.sonar.api.batch.Event; import org.sonar.api.batch.SonarIndex; import org.sonar.api.database.model.Snapshot; import org.sonar.api.design.Dependency; -import org.sonar.api.measures.Measure; -import org.sonar.api.measures.MeasuresFilter; -import org.sonar.api.measures.MeasuresFilters; -import org.sonar.api.measures.Metric; -import org.sonar.api.measures.MetricFinder; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.ProjectLink; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.Resource; -import org.sonar.api.resources.ResourceUtils; -import org.sonar.api.resources.Scopes; +import org.sonar.api.measures.*; +import org.sonar.api.resources.*; import org.sonar.api.rules.Rule; import org.sonar.api.rules.Violation; import org.sonar.api.utils.SonarException; @@ -53,14 +44,7 @@ import org.sonar.batch.issue.ModuleIssues; import org.sonar.core.component.ComponentKeys; import org.sonar.core.component.ScanGraph; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class DefaultIndex extends SonarIndex { @@ -347,9 +331,15 @@ public class DefaultIndex extends SonarIndex { } private static boolean isFiltered(Violation violation, ViolationQuery.SwitchMode mode) { - return mode == ViolationQuery.SwitchMode.BOTH - || (mode == ViolationQuery.SwitchMode.OFF && violation.isSwitchedOff()) - || (mode == ViolationQuery.SwitchMode.ON && !violation.isSwitchedOff()); + return mode == ViolationQuery.SwitchMode.BOTH || isSwitchOff(violation, mode) || isSwitchOn(violation, mode); + } + + private static boolean isSwitchOff(Violation violation, ViolationQuery.SwitchMode mode) { + return mode == ViolationQuery.SwitchMode.OFF && violation.isSwitchedOff(); + } + + private static boolean isSwitchOn(Violation violation, ViolationQuery.SwitchMode mode) { + return mode == ViolationQuery.SwitchMode.ON && !violation.isSwitchedOff(); } @Override diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java index fe97b91364d..03b6440d12e 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/MyBatis.java @@ -206,7 +206,7 @@ public class MyBatis implements BatchComponent, ServerComponent { new XMLMapperBuilder(input, configuration, mapperName, configuration.getSqlFragments()).parse(); configuration.addLoadedResource(mapperName); } catch (Exception e) { - throw new RuntimeException("Unable to load mapper " + mapperName, e); + throw new IllegalArgumentException("Unable to load mapper " + mapperName, e); } finally { Closeables.closeQuietly(input); } diff --git a/sonar-core/src/main/java/org/sonar/core/technicaldebt/TechnicalDebtXMLImporter.java b/sonar-core/src/main/java/org/sonar/core/technicaldebt/TechnicalDebtXMLImporter.java index df81a5d88bd..44ea20fbcd7 100644 --- a/sonar-core/src/main/java/org/sonar/core/technicaldebt/TechnicalDebtXMLImporter.java +++ b/sonar-core/src/main/java/org/sonar/core/technicaldebt/TechnicalDebtXMLImporter.java @@ -90,7 +90,8 @@ public class TechnicalDebtXMLImporter implements ServerExtension { return new SMInputFactory(xmlFactory); } - private Characteristic processCharacteristic(Model model, SMInputCursor chcCursor, ValidationMessages messages, TechnicalDebtRuleCache technicalDebtRuleCache) throws XMLStreamException { + private Characteristic processCharacteristic(Model model, SMInputCursor chcCursor, ValidationMessages messages, TechnicalDebtRuleCache technicalDebtRuleCache) + throws XMLStreamException { Characteristic characteristic = Characteristic.create(); SMInputCursor cursor = chcCursor.childElementCursor(); diff --git a/sonar-core/src/test/java/org/sonar/core/technicaldebt/TechnicalDebtCalculatorTest.java b/sonar-core/src/test/java/org/sonar/core/technicaldebt/TechnicalDebtCalculatorTest.java index c310b4c87f2..ef3289b938f 100644 --- a/sonar-core/src/test/java/org/sonar/core/technicaldebt/TechnicalDebtCalculatorTest.java +++ b/sonar-core/src/test/java/org/sonar/core/technicaldebt/TechnicalDebtCalculatorTest.java @@ -20,13 +20,13 @@ package org.sonar.core.technicaldebt; import com.google.common.collect.ListMultimap; -import com.google.common.collect.Lists; import org.apache.commons.lang.time.DateUtils; import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.issue.Issue; import org.sonar.api.issue.internal.DefaultIssue; +import org.sonar.api.measures.Measure; import org.sonar.api.measures.MeasuresFilter; import org.sonar.api.qualitymodel.Characteristic; import org.sonar.api.rule.RuleKey; @@ -39,6 +39,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; +import static com.google.common.collect.Lists.newArrayList; import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; @@ -52,13 +53,12 @@ public class TechnicalDebtCalculatorTest { private TechnicalDebtModel technicalDebtModel; private Functions functions; private TechnicalDebtCalculator remediationCostCalculator; - private TechnicalDebtConverter converter; @Before public void initMocks() { technicalDebtModel = mock(TechnicalDebtModel.class); functions = mock(Functions.class); - converter = mock(TechnicalDebtConverter.class); + TechnicalDebtConverter converter = mock(TechnicalDebtConverter.class); remediationCostCalculator = new TechnicalDebtCalculator(technicalDebtModel, functions, converter); } @@ -73,7 +73,7 @@ public class TechnicalDebtCalculatorTest { Violation violation3 = buildViolation("rule2", "repo2", NOW); Violation violation4 = buildViolation("unmatchable", "repo2", NOW); - List<Violation> violations = Lists.newArrayList(violation1, violation2, violation3, violation4); + List<Violation> violations = newArrayList(violation1, violation2, violation3, violation4); when(technicalDebtModel.getRequirementByRule("repo1", "rule1")).thenReturn(requirement1); when(technicalDebtModel.getRequirementByRule("repo2", "rule2")).thenReturn(requirement2); @@ -132,11 +132,11 @@ public class TechnicalDebtCalculatorTest { Violation violation3 = buildViolation("rule2", "repo2", YESTERDAY); Violation violation4 = buildViolation("rule2", "repo2", LAST_MONTH); - List<Violation> violations = Lists.newArrayList(violation1, violation2, violation3, violation4); + List<Violation> violations = newArrayList(violation1, violation2, violation3, violation4); when(technicalDebtModel.getRequirementByRule("repo1", "rule1")).thenReturn(requirement1); when(technicalDebtModel.getRequirementByRule("repo2", "rule2")).thenReturn(requirement2); - when(technicalDebtModel.getAllRequirements()).thenReturn(Lists.newArrayList(requirement1, requirement2)); + when(technicalDebtModel.getAllRequirements()).thenReturn(newArrayList(requirement1, requirement2)); when(functions.costInHours(any(TechnicalDebtRequirement.class), any(Collection.class))).thenReturn(1.0); @@ -152,6 +152,35 @@ public class TechnicalDebtCalculatorTest { } @Test + public void compute_totals_costs_from_children() throws Exception { + TechnicalDebtCharacteristic parentCharacteristic = new TechnicalDebtCharacteristic(Characteristic.create()); + TechnicalDebtRequirement requirement1 = new TechnicalDebtRequirement(Characteristic.create(), parentCharacteristic);; + + Violation violation1 = buildViolation("rule1", "repo1", NOW); + Violation violation2 = buildViolation("rule1", "repo1", NOW); + Violation violation3 = buildViolation("rule2", "repo2", YESTERDAY); + Violation violation4 = buildViolation("rule2", "repo2", LAST_MONTH); + + List<Violation> violations = newArrayList(violation1, violation2, violation3, violation4); + + when(technicalDebtModel.getRequirementByRule("repo1", "rule1")).thenReturn(requirement1); + when(technicalDebtModel.getAllRequirements()).thenReturn(newArrayList(requirement1)); + + when(functions.costInHours(any(TechnicalDebtRequirement.class), any(Collection.class))).thenReturn(1.0); + + DecoratorContext context = mock(DecoratorContext.class); + when(context.getViolations()).thenReturn(violations); + + Measure measure = new Measure().setCharacteristic(requirement1.toCharacteristic()).setValue(5.0); + when(context.getChildrenMeasures(any(MeasuresFilter.class))).thenReturn(newArrayList(measure)); + + remediationCostCalculator.compute(context); + + assertThat(remediationCostCalculator.getTotal()).isEqualTo(6.0); + assertThat(remediationCostCalculator.getRequirementCosts().get(requirement1)).isEqualTo(6.0); + } + + @Test public void technical_debt_from_one_issue() throws Exception { DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(RuleKey.of("squid", "AvoidCycle")); TechnicalDebtRequirement requirement = mock(TechnicalDebtRequirement.class); @@ -163,7 +192,7 @@ public class TechnicalDebtCalculatorTest { } @Test - public void no_technical_debt_from_one_issue_if_reauirement_not_found() throws Exception { + public void no_technical_debt_from_one_issue_if_requirement_not_found() throws Exception { DefaultIssue issue = new DefaultIssue().setKey("ABCDE").setRuleKey(RuleKey.of("squid", "AvoidCycle")); when(technicalDebtModel.getRequirementByRule("squid", "AvoidCycle")).thenReturn(null); diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/issue/internal/IssueJsonParser.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/issue/internal/IssueJsonParser.java index d5c6fa201f0..9640d2520fc 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/issue/internal/IssueJsonParser.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/issue/internal/IssueJsonParser.java @@ -38,10 +38,13 @@ import java.util.Map; */ public class IssueJsonParser { + private static final String ISSUES = "issues"; + private static final String TOTAL = "total"; + public Issues parseIssues(String json) { DefaultIssues result = new DefaultIssues(); Map jsonRoot = (Map) JSONValue.parse(json); - List<Map> jsonIssues = (List<Map>) jsonRoot.get("issues"); + List<Map> jsonIssues = (List<Map>) jsonRoot.get(ISSUES); if (jsonIssues != null) { for (Map jsonIssue : jsonIssues) { result.add(new DefaultIssue(jsonIssue)); @@ -132,11 +135,11 @@ public class IssueJsonParser { Map jsonRoot = (Map) JSONValue.parse(json); Map issuesChanged = (Map) jsonRoot.get("issuesChanged"); - result.setTotalIssuesChanged(JsonUtils.getInteger(issuesChanged, "total")); + result.setTotalIssuesChanged(JsonUtils.getInteger(issuesChanged, TOTAL)); Map issuesNotChanged = (Map) jsonRoot.get("issuesNotChanged"); - result.setTotalIssuesNotChanged(JsonUtils.getInteger(issuesNotChanged, "total")); - JSONArray issuesJson = JsonUtils.getArray(issuesNotChanged, "issues"); + result.setTotalIssuesNotChanged(JsonUtils.getInteger(issuesNotChanged, TOTAL)); + JSONArray issuesJson = JsonUtils.getArray(issuesNotChanged, ISSUES); if (issuesJson != null) { result.setIssuesNotChanged(issuesJson); } diff --git a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/RuleUnmarshaller.java b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/RuleUnmarshaller.java index a634c62a0bb..58242f95a36 100644 --- a/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/RuleUnmarshaller.java +++ b/sonar-ws-client/src/main/java/org/sonar/wsclient/unmarshallers/RuleUnmarshaller.java @@ -31,6 +31,8 @@ import java.util.List; */ public class RuleUnmarshaller extends AbstractUnmarshaller<Rule> { + private static final String DESCRIPTION = "description"; + @Override protected Rule parse(Object json) { Rule rule = new Rule(); @@ -46,7 +48,7 @@ public class RuleUnmarshaller extends AbstractUnmarshaller<Rule> { .setKey(utils.getString(json, "key")) .setConfigKey(utils.getString(json, "config_key")) .setRepository(utils.getString(json, "plugin")) - .setDescription(utils.getString(json, "description")) + .setDescription(utils.getString(json, DESCRIPTION)) .setSeverity(utils.getString(json, "priority")) .setActive("ACTIVE".equals(utils.getString(json, "status"))); } @@ -80,7 +82,7 @@ public class RuleUnmarshaller extends AbstractUnmarshaller<Rule> { RuleParam param = new RuleParam(); param.setName(utils.getString(json, "name")) - .setDescription(utils.getString(json, "description")) + .setDescription(utils.getString(json, DESCRIPTION)) .setValue(utils.getString(json, "value")); return param; } |