From 2bbefed97d114cfd43b7e4f5c16bdf753297e96d Mon Sep 17 00:00:00 2001 From: David Gageot Date: Mon, 29 Oct 2012 11:07:06 +0100 Subject: [PATCH] SONAR-3895 Streaming export --- .../org/sonar/batch/local/DryRunExporter.java | 70 ++++++++++++++----- .../sonar/batch/local/DryRunExporterTest.java | 27 ++++++- .../persistence/DryRunDatabaseFactory.java | 2 +- 3 files changed, 81 insertions(+), 18 deletions(-) diff --git a/sonar-batch/src/main/java/org/sonar/batch/local/DryRunExporter.java b/sonar-batch/src/main/java/org/sonar/batch/local/DryRunExporter.java index 7323077518e..a079a4feb7c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/local/DryRunExporter.java +++ b/sonar-batch/src/main/java/org/sonar/batch/local/DryRunExporter.java @@ -19,22 +19,29 @@ */ package org.sonar.batch.local; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.io.Closeables; import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.stream.JsonWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; import org.sonar.api.batch.SensorContext; import org.sonar.api.resources.Resource; import org.sonar.api.rules.Violation; -import org.sonar.api.violations.ViolationQuery; +import org.sonar.api.utils.SonarException; import org.sonar.batch.bootstrap.DryRun; import org.sonar.batch.index.DefaultIndex; -import java.io.Serializable; +import javax.annotation.Nullable; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Collection; import java.util.List; -import java.util.Map; /** * @since 3.4 @@ -55,22 +62,53 @@ public class DryRunExporter implements BatchComponent { return; } - LOG.info("Exporting dry run results"); + LOG.info("Exporting DryRun results"); + + String json = getResultsAsJson(sonarIndex.getResources()); + System.out.println(json); + } - List> results = Lists.newArrayList(); + @VisibleForTesting + String getResultsAsJson(Collection resources) { + Gson gson = new Gson(); - for (Resource resource : sonarIndex.getResources()) { - List violations = sonarIndex.getViolations(ViolationQuery.create().forResource(resource)); - for (Violation violation : violations) { - results.add(ImmutableMap.of( - "resource", violation.getResource().getKey(), - "line", violation.getLineId(), - "message", violation.getMessage())); + StringWriter output = new StringWriter(); + JsonWriter writer = null; + try { + writer = new JsonWriter(output); + writer.beginArray(); + + for (Resource resource : resources) { + for (Violation violation : getViolations(resource)) { + gson.toJson(new ViolationToMap().apply(violation), writer); + } } + + writer.endArray(); + } catch (IOException e) { + throw new SonarException("Unable to export results", e); + } finally { + Closeables.closeQuietly(writer); } - String json = new Gson().toJson(results); - System.out.println(json); + return output.toString(); + } + + @VisibleForTesting + List getViolations(Resource resource) { + return sonarIndex.getViolations(resource); + } + + static class ViolationToMap implements Function { + public JsonElement apply(@Nullable Violation violation) { + JsonObject json = new JsonObject(); + if (violation != null) { + json.addProperty("resource", violation.getResource().getKey()); + json.addProperty("line", violation.getLineId()); + json.addProperty("message", violation.getMessage()); + } + return json; + } } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/local/DryRunExporterTest.java b/sonar-batch/src/test/java/org/sonar/batch/local/DryRunExporterTest.java index bb09e9c3f18..3e7ab3af29d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/local/DryRunExporterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/local/DryRunExporterTest.java @@ -19,14 +19,24 @@ */ package org.sonar.batch.local; +import com.google.common.collect.ImmutableSet; import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Resource; +import org.sonar.api.rules.Violation; import org.sonar.batch.bootstrap.DryRun; import org.sonar.batch.index.DefaultIndex; +import org.sonar.java.api.JavaClass; +import java.util.Arrays; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; public class DryRunExporterTest { DryRunExporter dryRunExporter; @@ -34,10 +44,12 @@ public class DryRunExporterTest { DryRun dryRun = mock(DryRun.class); DefaultIndex sonarIndex = mock(DefaultIndex.class); SensorContext sensorContext = mock(SensorContext.class); + Resource resource = JavaClass.create("KEY"); + Violation violation = mock(Violation.class); @Before public void setUp() { - dryRunExporter = new DryRunExporter(dryRun, sonarIndex); + dryRunExporter = spy(new DryRunExporter(dryRun, sonarIndex)); } @Test @@ -46,4 +58,17 @@ public class DryRunExporterTest { verifyZeroInteractions(sensorContext, sonarIndex); } + + @Test + public void should_export_violations() { + when(dryRun.isEnabled()).thenReturn(true); + when(violation.getResource()).thenReturn(resource); + when(violation.getLineId()).thenReturn(1); + when(violation.getMessage()).thenReturn("VIOLATION"); + doReturn(Arrays.asList(violation)).when(dryRunExporter).getViolations(resource); + + String json = dryRunExporter.getResultsAsJson(ImmutableSet.of(resource)); + + assertThat(json).isEqualTo("[{\"resource\":\"KEY\",\"line\":1,\"message\":\"VIOLATION\"}]"); + } } diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DryRunDatabaseFactory.java b/sonar-core/src/main/java/org/sonar/core/persistence/DryRunDatabaseFactory.java index 4b53e7eeae0..6b3c7c6e065 100644 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DryRunDatabaseFactory.java +++ b/sonar-core/src/main/java/org/sonar/core/persistence/DryRunDatabaseFactory.java @@ -58,7 +58,7 @@ public class DryRunDatabaseFactory implements ServerComponent { return dbFileContent(name); } catch (SQLException e) { - throw new SonarException("Unable to create database for dry run", e); + throw new SonarException("Unable to create database for DryRun", e); } } -- 2.39.5