]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6750 Support new SQ Runner API for retrieving issues 451/head
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Wed, 29 Jul 2015 08:34:22 +0000 (10:34 +0200)
committerDuarte Meneses <duarte.meneses@sonarsource.com>
Thu, 30 Jul 2015 11:18:19 +0000 (13:18 +0200)
22 files changed:
sonar-batch-protocol/src/main/java/org/sonar/batch/protocol/input/Rule.java
sonar-batch-protocol/src/test/java/org/sonar/batch/protocol/input/RulesSearchResultTest.java
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/IssueListener.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/DefaultProjectIssues.java
sonar-batch/src/main/java/org/sonar/batch/issue/IssueCallback.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
sonar-batch/src/main/java/org/sonar/batch/phases/PhaseExecutor.java
sonar-batch/src/main/java/org/sonar/batch/rule/DefaultRulesLoader.java
sonar-batch/src/main/java/org/sonar/batch/rule/RulesProvider.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java
sonar-batch/src/main/java/org/sonar/batch/scan/report/Reporter.java
sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java [new file with mode: 0644]
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ChecksMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/MultilineIssuesMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/rule/DefaultRulesLoaderTest.java
sonar-batch/src/test/java/org/sonar/batch/rule/RulesProviderTest.java
sonar-ws/.gitignore [new file with mode: 0644]

index e1574f1c6be7ee139bcf03bafcfe5ec0dfb45adc..8f71f3ff00a470d36c49cf554e5ea57e1bc46751 100644 (file)
  */
 package org.sonar.batch.protocol.input;
 
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
 public class Rule {
   private final String key;
   private final String repo;
   private final String internalKey;
   private final String name;
-  private final String severity;
-  private final String lang;
 
-  public Rule(String ruleKey, String repositoryKey, String internalKey, String name, @Nullable String severity, @Nullable String language) {
+  public Rule(String ruleKey, String repositoryKey, String internalKey, String name) {
     this.key = ruleKey;
     this.repo = repositoryKey;
     this.internalKey = internalKey;
     this.name = name;
-    this.severity = severity;
-    this.lang = language;
   }
 
   public String ruleKey() {
@@ -55,20 +48,4 @@ public class Rule {
     return name;
   }
 
-  /**
-   * Is null on manual rules
-   */
-  @CheckForNull
-  public String severity() {
-    return severity;
-  }
-
-  /**
-   * Is null on manual rules
-   */
-  @CheckForNull
-  public String language() {
-    return lang;
-  }
-
 }
index 0455cc2eeb1f39027379ada6bd89c5ff7c82f5b6..0781a69b78f827826da12c233316d7bd5a95f9b0 100644 (file)
@@ -33,9 +33,9 @@ import org.junit.Test;
 public class RulesSearchResultTest {
   @Test
   public void testJsonParsing() {
-    Rule rule1 = new Rule("squid:S1194", "squid", "S1194", "\"java.lang.Error\" should not be extended", "MAJOR", "java");
+    Rule rule1 = new Rule("squid:S1194", "squid", "S1194", "\"java.lang.Error\" should not be extended");
     Rule rule2 = new Rule("squid:ObjectFinalizeOverridenCallsSuperFinalizeCheck", "squid", "ObjectFinalizeOverridenCallsSuperFinalizeCheck",
-      "super.finalize() should be called at the end of Object.finalize() implementations", "BLOCKER", "java");
+      "super.finalize() should be called at the end of Object.finalize() implementations");
 
     RulesSearchResult rules = new RulesSearchResult();
     rules.setRules(Lists.newArrayList(rule1, rule2));
index fa261e9176cdd2f269f82197fe4980f46fc70b0e..5cbcfe3671d6c3adcb588bcba75a211decdf347c 100644 (file)
@@ -100,14 +100,36 @@ public final class Batch {
    * @since 4.4
    */
   public Batch executeTask(Map<String, String> analysisProperties, Object... components) {
-    if (!started) {
-      throw new IllegalStateException("Batch is not started. Unable to execute task.");
-    }
+    checkStarted();
+    bootstrapContainer.executeAnalysis(analysisProperties, components);
+    return this;
+  }
 
+  /**
+   * @since 5.2
+   */
+  public Batch executeTask(Map<String, String> analysisProperties) {
+    checkStarted();
     bootstrapContainer.executeAnalysis(analysisProperties, components);
     return this;
   }
 
+  /**
+   * @since 5.2
+   */
+  public Batch executeTask(Map<String, String> analysisProperties, IssueListener issueListener) {
+    checkStarted();
+    components.add(issueListener);
+    bootstrapContainer.executeAnalysis(analysisProperties, components);
+    return this;
+  }
+
+  private void checkStarted() {
+    if (!started) {
+      throw new IllegalStateException("Batch is not started. Unable to execute task.");
+    }
+  }
+
   /**
    * @since 4.4
    */
@@ -116,12 +138,8 @@ public final class Batch {
   }
 
   private void doStop(boolean swallowException) {
-    if (!started) {
-      throw new IllegalStateException("Batch is not started.");
-    }
-
+    checkStarted();
     bootstrapContainer.stopComponents(swallowException);
-
     this.started = false;
   }
 
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/IssueListener.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/IssueListener.java
new file mode 100644 (file)
index 0000000..a8369b0
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.bootstrapper;
+
+import org.sonar.api.issue.Issue;
+
+public interface IssueListener {
+  void handle(Issue issue);
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java b/sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java
new file mode 100644 (file)
index 0000000..f148ebf
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.issue;
+
+import org.sonar.batch.bootstrapper.IssueListener;
+
+import org.sonar.core.issue.DefaultIssue;
+
+public class DefaultIssueCallback implements IssueCallback {
+  private final IssueCache issues;
+  private final IssueListener listener;
+
+  public DefaultIssueCallback(IssueCache issues, IssueListener listener) {
+    this.issues = issues;
+    this.listener = listener;
+  }
+
+  /**
+   * If no listener exists, this constructor will be used by pico.
+   */
+  public DefaultIssueCallback(IssueCache issues) {
+    this(issues, null);
+  }
+
+  @Override
+  public void execute() {
+    if (listener == null) {
+      return;
+    }
+
+    for (DefaultIssue issue : issues.all()) {
+      listener.handle(issue);
+    }
+  }
+}
index ed9de9a5defa0eecdacd8174c3c9f1645c91598a..9f869ca95ef0d8d1424dddbd25cb5e6d6626cfd9 100644 (file)
@@ -59,7 +59,7 @@ public class DefaultProjectIssues implements ProjectIssues {
     @Override
     public boolean apply(@Nullable DefaultIssue issue) {
       if (issue != null) {
-        return resolved ? issue.resolution() != null : issue.resolution() == null;
+        return resolved ? (issue.resolution() != null) : (issue.resolution() == null);
       }
       return false;
     }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/IssueCallback.java b/sonar-batch/src/main/java/org/sonar/batch/issue/IssueCallback.java
new file mode 100644 (file)
index 0000000..25b01ee
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.issue;
+
+public interface IssueCallback {
+  void execute();
+}
index 6cf1c15157dbef223d2032fba6309f98bc870406..1be6d3194aa21c5384f920c6a77559d4ff9dc16d 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.mediumtest;
 
-import org.sonar.api.server.rule.RulesDefinition.Repository;
+import org.sonar.batch.bootstrapper.IssueListener;
 
+import org.sonar.api.server.rule.RulesDefinition.Repository;
 import org.sonar.api.server.rule.RulesDefinition;
 import org.sonar.batch.protocol.input.RulesSearchResult;
 import org.sonar.batch.rule.RulesLoader;
@@ -144,7 +145,7 @@ public class BatchMediumTester {
       List<Repository> repositories = context.repositories();
       for (Repository repo : repositories) {
         for (RulesDefinition.Rule rule : repo.rules()) {
-          this.addRule(new Rule(rule.repository().key() + ":" + rule.key(), rule.repository().key(), rule.internalKey(), rule.name(), rule.severity(), repo.language()));
+          this.addRule(new Rule(rule.repository().key() + ":" + rule.key(), rule.repository().key(), rule.internalKey(), rule.name()));
         }
       }
       return this;
@@ -234,6 +235,7 @@ public class BatchMediumTester {
   public static class TaskBuilder {
     private final Map<String, String> taskProperties = new HashMap<>();
     private BatchMediumTester tester;
+    private IssueListener issueListener = null;
 
     public TaskBuilder(BatchMediumTester tester) {
       this.tester = tester;
@@ -243,7 +245,11 @@ public class BatchMediumTester {
       TaskResult result = new TaskResult();
       Map<String, String> props = new HashMap<>();
       props.putAll(taskProperties);
-      tester.batch.executeTask(props, result);
+      if (issueListener != null) {
+        tester.batch.executeTask(props, result, issueListener);
+      } else {
+        tester.batch.executeTask(props, result);
+      }
       return result;
     }
 
@@ -256,6 +262,11 @@ public class BatchMediumTester {
       taskProperties.put(key, value);
       return this;
     }
+
+    public TaskBuilder setIssueListener(IssueListener issueListener) {
+      this.issueListener = issueListener;
+      return this;
+    }
   }
 
   private static class FakeRulesLoader implements RulesLoader {
index 7daea18961d9756e04682fdbe1ce863d22e4174e..08152c55fbe3e0bd06f78b9ce64c4584059a562f 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.phases;
 
-import org.sonar.batch.scan.ProjectAnalysisMode;
+import org.sonar.batch.issue.IssueCallback;
 
+import org.sonar.batch.scan.ProjectAnalysisMode;
 import org.sonar.api.batch.SensorContext;
 import org.sonar.api.resources.Project;
 import org.sonar.batch.events.BatchStepEvent;
@@ -51,12 +52,13 @@ public final class PhaseExecutor {
   private final IssuesReports issuesReport;
   private final ProjectAnalysisMode analysisMode;
   private final LocalIssueTracking localIssueTracking;
+  private final IssueCallback issueCallback;
 
   public PhaseExecutor(InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor,
     SensorContext sensorContext, DefaultIndex index,
     EventBus eventBus, ReportPublisher reportPublisher, ProjectInitializer pi,
     FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier,
-    IssueExclusionsLoader issueExclusionsLoader, ProjectAnalysisMode analysisMode, LocalIssueTracking localIssueTracking) {
+    IssueExclusionsLoader issueExclusionsLoader, ProjectAnalysisMode analysisMode, LocalIssueTracking localIssueTracking, IssueCallback issueCallback) {
     this.postJobsExecutor = postJobsExecutor;
     this.initializersExecutor = initializersExecutor;
     this.sensorsExecutor = sensorsExecutor;
@@ -72,6 +74,7 @@ public final class PhaseExecutor {
     this.issueExclusionsLoader = issueExclusionsLoader;
     this.analysisMode = analysisMode;
     this.localIssueTracking = localIssueTracking;
+    this.issueCallback = issueCallback;
   }
 
   /**
@@ -98,6 +101,7 @@ public final class PhaseExecutor {
     if (module.isRoot()) {
       if (analysisMode.isPreview()) {
         localIssueTracking();
+        issuesCallback();
       }
       issuesReport();
       publishReportJob();
@@ -121,6 +125,13 @@ public final class PhaseExecutor {
     eventBus.fireEvent(new BatchStepEvent(stepName, false));
   }
 
+  private void issuesCallback() {
+    String stepName = "Issues Callback";
+    eventBus.fireEvent(new BatchStepEvent(stepName, true));
+    issueCallback.execute();
+    eventBus.fireEvent(new BatchStepEvent(stepName, false));
+  }
+
   private void issuesReport() {
     String stepName = "Issues Reports";
     eventBus.fireEvent(new BatchStepEvent(stepName, true));
index a14ad0dec9535b7896dfa510bad9dba38451e15c..fcb2fa3d67d3008853c3d961049514620595330d 100644 (file)
@@ -23,7 +23,7 @@ import org.sonar.batch.protocol.input.RulesSearchResult;
 import org.sonar.batch.bootstrap.WSLoader;
 
 public class DefaultRulesLoader implements RulesLoader {
-  private static final String RULES_SEARCH_URL = "/api/rules/search?ps=500&f=repo,name,internalKey,severity,lang";
+  private static final String RULES_SEARCH_URL = "/api/rules/search?ps=500&f=repo,name,internalKey";
 
   private final WSLoader wsLoader;
 
index c864489149c4f22d313c3e02ab46e4307bb68271..8e3c1ce75c0e9d141715af551d70b68261dfe51f 100644 (file)
@@ -43,7 +43,6 @@ public class RulesProvider extends ProviderAdapter {
     for (Rule inputRule : ref.load().getRules()) {
       NewRule newRule = builder.add(RuleKey.parse(inputRule.ruleKey()));
       newRule.setName(inputRule.name());
-      newRule.setSeverity(inputRule.severity());
       newRule.setInternalKey(inputRule.internalKey());
     }
 
index 30bd5a2ff26093ed6b344949d25ff727637f369a..ea086f5a068a8d52f37e9ad644f5be9c2c36ec65 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.batch.scan;
 
+import org.sonar.batch.issue.DefaultIssueCallback;
+
 import com.google.common.annotations.VisibleForTesting;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.InstantiationStrategy;
@@ -141,6 +143,7 @@ public class ProjectScanContainer extends ComponentContainer {
       DefaultFileLinesContextFactory.class,
       Caches.class,
       BatchComponentCache.class,
+      DefaultIssueCallback.class,
 
       // temp
       new ProjectTempFolderProvider(),
index 7dd9db0d18d52a3560cf695c0d773c106816b03f..b7520f538216f3fdd506c4e315fa76baccc86e62 100644 (file)
@@ -102,7 +102,7 @@ public class JSONReport implements Reporter {
   private void exportResults(String exportPath) {
     File exportFile = new File(fileSystem.workDir(), exportPath);
 
-    LOG.info("Export issues to " + exportFile.getAbsolutePath());
+    LOG.info("Export issues to {}", exportFile.getAbsolutePath());
     try (Writer output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(exportFile), StandardCharsets.UTF_8))) {
       writeJson(output);
 
@@ -190,7 +190,7 @@ public class JSONReport implements Reporter {
     json.endArray();
   }
 
-  private void writeJsonModuleComponents(JsonWriter json, Project module) {
+  private static void writeJsonModuleComponents(JsonWriter json, Project module) {
     json
       .beginObject()
       .prop("key", module.getEffectiveKey())
index 1476cf219d53bf9d6497fad3e989f1fa2f742dfe..f62db54c8b95ef825ced48df644dd6b551e0ed19 100644 (file)
@@ -24,6 +24,6 @@ import org.sonar.api.batch.BatchSide;
 @BatchSide
 public interface Reporter {
 
-  public void execute();
+  void execute();
 
 }
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java
new file mode 100644 (file)
index 0000000..1acdd57
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.batch.issue;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import org.sonar.batch.bootstrapper.IssueListener;
+import org.junit.Before;
+import com.google.common.collect.ImmutableList;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.api.issue.Issue;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Test;
+
+public class DefaultIssueCallbackTest {
+  private IssueCache issueCache;
+  private DefaultIssue issue;
+
+  @Before
+  public void setUp() {
+    issue = new DefaultIssue();
+    issue.setKey("key");
+
+    issueCache = mock(IssueCache.class);
+    when(issueCache.all()).thenReturn(ImmutableList.of(issue));
+  }
+
+  @Test
+  public void testWithoutListener() {
+    DefaultIssueCallback issueCallback = new DefaultIssueCallback(issueCache);
+    issueCallback.execute();
+  }
+
+  @Test
+  public void testWithListener() {
+    final List<Issue> issueList = new LinkedList<>();
+    IssueListener listener = new IssueListener() {
+      @Override
+      public void handle(Issue issue) {
+        issueList.add(issue);
+      }
+    };
+
+    DefaultIssueCallback issueCallback = new DefaultIssueCallback(issueCache, listener);
+    issueCallback.execute();
+    
+    assertThat(issueList).containsExactly(issue);
+  }
+
+}
index 7d39819f825e73390477456e60d58b25aa8d36c8..d5bd3b44c9aedd1ec637cddc8e2f2c44670cb42b 100644 (file)
@@ -47,8 +47,8 @@ public class ChecksMediumTest {
     .registerPlugin("xoo", new XooPlugin())
     .addRules(new XooRulesDefinition())
     .addDefaultQProfile("xoo", "Sonar Way")
-    .addRule(new Rule("xoo:TemplateRule_1234", "xoo", "TemplateRule_1234", "A template rule", "MAJOR", "xoo"))
-    .addRule(new Rule("xoo:TemplateRule_1235", "xoo", "TemplateRule_1235", "Another template rule", "MAJOR", "xoo"))
+    .addRule(new Rule("xoo:TemplateRule_1234", "xoo", "TemplateRule_1234", "A template rule"))
+    .addRule(new Rule("xoo:TemplateRule_1235", "xoo", "TemplateRule_1235", "Another template rule"))
     .activateRule(new ActiveRule("xoo", "TemplateRule_1234", "TemplateRule", "A template rule", "MAJOR", null, "xoo").addParam("line", "1"))
     .activateRule(new ActiveRule("xoo", "TemplateRule_1235", "TemplateRule", "Another template rule", "MAJOR", null, "xoo").addParam("line", "2"))
     .build();
index 6898c5bfcc94f5c13135c1167baea5790fbb1a75..1399a135f72350a321c3e57b30f159faa2cbc91a 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.mediumtest.issues;
 
+import org.sonar.api.issue.Issue;
+import org.sonar.batch.bootstrapper.IssueListener;
 import org.sonar.xoo.rule.XooRulesDefinition;
-
 import com.google.common.collect.ImmutableMap;
 import org.apache.commons.io.FileUtils;
 import org.junit.After;
@@ -35,6 +36,8 @@ import org.sonar.xoo.XooPlugin;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -49,15 +52,60 @@ public class IssuesMediumTest {
     .addRules(new XooRulesDefinition())
     .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo"))
     .build();
+  
+  public BatchMediumTester testerPreview = BatchMediumTester.builder()
+    .registerPlugin("xoo", new XooPlugin())
+    .addDefaultQProfile("xoo", "Sonar Way")
+    .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "preview"))
+    .addRules(new XooRulesDefinition())
+    .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo"))
+    .build();
 
   @Before
   public void prepare() {
     tester.start();
+    testerPreview.start();
   }
 
   @After
   public void stop() {
     tester.stop();
+    testerPreview.stop();
+  }
+
+  @Test
+  public void testIssueCallback() throws Exception {
+    File projectDir = new File(IssuesMediumTest.class.getResource("/mediumtest/xoo/sample").toURI());
+    File tmpDir = temp.newFolder();
+    FileUtils.copyDirectory(projectDir, tmpDir);
+    IssueRecorder issueListener = new IssueRecorder();
+
+    TaskResult result = testerPreview
+      .newScanTask(new File(tmpDir, "sonar-project.properties"))
+      .setIssueListener(issueListener)
+      .property("sonar.analysis.mode", "preview")
+      .start();
+
+    assertThat(result.issues()).hasSize(14);
+    assertThat(issueListener.issueList).hasSize(14);
+
+    assertThat(result.issues()).containsExactlyElementsOf(issueListener.issueList);
+  }
+
+  @Test
+  public void testNoIssueCallbackInNonPreview() throws Exception {
+    File projectDir = new File(IssuesMediumTest.class.getResource("/mediumtest/xoo/sample").toURI());
+    File tmpDir = temp.newFolder();
+    FileUtils.copyDirectory(projectDir, tmpDir);
+    IssueRecorder issueListener = new IssueRecorder();
+
+    TaskResult result = tester
+      .newScanTask(new File(tmpDir, "sonar-project.properties"))
+      .setIssueListener(issueListener)
+      .start();
+
+    assertThat(result.issues()).hasSize(14);
+    assertThat(issueListener.issueList).hasSize(0);
   }
 
   @Test
@@ -152,4 +200,12 @@ public class IssuesMediumTest {
     assertThat(foundIssueAtLine1).isTrue();
   }
 
+  private class IssueRecorder implements IssueListener {
+    List<Issue> issueList = new LinkedList<>();
+
+    @Override
+    public void handle(Issue issue) {
+      issueList.add(issue);
+    }
+  }
 }
index c07dd6cdbc680d799a71dc0984056a29de2d572b..02b61ca0cdbaa90fe095ee4efc4fb2fadff0fb8d 100644 (file)
@@ -44,7 +44,7 @@ public class MultilineIssuesMediumTest {
   public BatchMediumTester tester = BatchMediumTester.builder()
     .registerPlugin("xoo", new XooPlugin())
     .addRules(new XooRulesDefinition())
-    .addRule(new Rule("xoo:MultilineIssue", "xoo", null, "Multinile Issue", "MAJOR", "xoo"))
+    .addRule(new Rule("xoo:MultilineIssue", "xoo", null, "Multinile Issue"))
     .addDefaultQProfile("xoo", "Sonar Way")
     .activateRule(new ActiveRule("xoo", "MultilineIssue", null, "Multinile Issue", "MAJOR", null, "xoo"))
     .build();
index 9dae8576ce33a0d11d9be6c00599294ed64c94e3..e09631ac9fd6eb74d3929908c45a7927e7c91b70 100644 (file)
@@ -69,8 +69,8 @@ public class PreviewAndReportsMediumTest {
     .registerPlugin("xoo", new XooPlugin())
     .addDefaultQProfile("xoo", "Sonar Way")
     .addRules(new XooRulesDefinition())
-    .addRule(new Rule("manual:MyManualIssue", "manual", "MyManualIssue", "My manual issue", "MAJOR", null))
-    .addRule(new Rule("manual:MyManualIssueDup", "manual", "MyManualIssue", "My manual issue", "MAJOR", null))
+    .addRule(new Rule("manual:MyManualIssue", "manual", "MyManualIssue", "My manual issue"))
+    .addRule(new Rule("manual:MyManualIssueDup", "manual", "MyManualIssue", "My manual issue"))
     .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo"))
     .activateRule(new ActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null))
     .setPreviousAnalysisDate(new Date())
index 49ecaa0bcc9ee1ee917ca36ee23b155768c70677..a9d5bfd4571f46a9f159fc5022b174a346a08d40 100644 (file)
@@ -36,9 +36,9 @@ import org.sonar.batch.protocol.input.RulesSearchResult;
 public class DefaultRulesLoaderTest {
   @Test
   public void testLoadingJson() throws IOException {
-    Rule rule1 = new Rule("squid:S1194", "squid", "S1194", "\"java.lang.Error\" should not be extended", "MAJOR", "java");
+    Rule rule1 = new Rule("squid:S1194", "squid", "S1194", "\"java.lang.Error\" should not be extended");
     Rule rule2 = new Rule("squid:ObjectFinalizeOverridenCallsSuperFinalizeCheck", "squid", "ObjectFinalizeOverridenCallsSuperFinalizeCheck",
-      "super.finalize() should be called at the end of Object.finalize() implementations", "BLOCKER", "java");
+      "super.finalize() should be called at the end of Object.finalize() implementations");
 
     // generate json
     RulesSearchResult rulesSearch = new RulesSearchResult();
index 84e36977b7ce8a93fbfd122ed60ad2f355b98964..cfa69b5da8f1c5698fe7fbdab19466d4e3912678 100644 (file)
@@ -35,7 +35,7 @@ import org.junit.Test;
 public class RulesProviderTest {
   @Test
   public void testRuleTranslation() {
-    final Rule testRule = new Rule("repo1:key1", "repo1", "key1", "name", "severity", "language");
+    final Rule testRule = new Rule("repo1:key1", "repo1", "key1", "name");
 
     RulesSearchResult loadResult = new RulesSearchResult();
     loadResult.setRules(Arrays.asList(testRule));
@@ -53,7 +53,6 @@ public class RulesProviderTest {
         return value.key().rule().equals(testRule.internalKey()) &&
           value.internalKey().equals(testRule.internalKey()) &&
           value.name().equals(testRule.name()) &&
-          value.severity().equals(testRule.severity()) &&
           value.key().repository().equals(testRule.repositoryKey());
       }
     });
diff --git a/sonar-ws/.gitignore b/sonar-ws/.gitignore
new file mode 100644 (file)
index 0000000..b83d222
--- /dev/null
@@ -0,0 +1 @@
+/target/