]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6978 Provide enhanced issue locations (start/end) offset in issues mode 621/head
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Thu, 5 Nov 2015 13:14:35 +0000 (14:14 +0100)
committerDuarte Meneses <duarte.meneses@sonarsource.com>
Mon, 9 Nov 2015 15:58:03 +0000 (16:58 +0100)
42 files changed:
it/it-projects/shared/xoo-precise-issues/sonar-project.properties [new file with mode: 0644]
it/it-projects/shared/xoo-precise-issues/src/main/xoo/sample/Sample.xoo [new file with mode: 0644]
it/it-tests/src/test/java/it/analysis/IssueJsonReportTest.java
it/it-tests/src/test/java/it/analysis/IssuesModeTest.java
it/it-tests/src/test/resources/analysis/IssueJsonReportTest/multiline.xml [new file with mode: 0644]
it/it-tests/src/test/resources/analysis/IssueJsonReportTest/no-server-analysis.json
it/it-tests/src/test/resources/analysis/IssueJsonReportTest/report-on-root-module.json
it/it-tests/src/test/resources/analysis/IssueJsonReportTest/report-on-single-module-branch.json
it/it-tests/src/test/resources/analysis/IssueJsonReportTest/report-on-single-module.json
it/it-tests/src/test/resources/analysis/IssueJsonReportTest/report-on-sub-module.json
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/IssueListener.java
sonar-batch/src/main/java/org/sonar/batch/issue/DefaultIssueCallback.java
sonar-batch/src/main/java/org/sonar/batch/issue/DefaultProjectIssues.java
sonar-batch/src/main/java/org/sonar/batch/issue/IssueCache.java
sonar-batch/src/main/java/org/sonar/batch/issue/IssueTransformer.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/TrackedIssueAdapter.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTransition.java
sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java
sonar-batch/src/main/java/org/sonar/batch/issue/tracking/TrackedIssue.java [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/mediumtest/TaskResult.java
sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java
sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java
sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java
sonar-batch/src/main/java/org/sonar/batch/scan/report/JSONReport.java
sonar-batch/src/main/java/org/sonar/batch/scan/report/ReportSummary.java
sonar-batch/src/main/java/org/sonar/batch/scan/report/ResourceReport.java
sonar-batch/src/main/resources/org/sonar/batch/scan/report/issuesreport.ftl
sonar-batch/src/test/java/org/sonar/batch/issue/DefaultIssueCallbackTest.java
sonar-batch/src/test/java/org/sonar/batch/issue/DefaultProjectIssuesTest.java
sonar-batch/src/test/java/org/sonar/batch/issue/IssueCacheTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/EmptyFileTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java
sonar-batch/src/test/java/org/sonar/batch/mediumtest/issuesmode/ScanOnlyChangedTest.java
sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/report/ConsoleReportTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/report/JSONReportTest.java
sonar-batch/src/test/resources/org/sonar/batch/scan/report/JSONReportTest/report.json
sonar-core/src/main/java/org/sonar/core/issue/IssueUpdater.java
sonar-core/src/main/java/org/sonar/core/issue/workflow/IssueWorkflow.java

diff --git a/it/it-projects/shared/xoo-precise-issues/sonar-project.properties b/it/it-projects/shared/xoo-precise-issues/sonar-project.properties
new file mode 100644 (file)
index 0000000..1a7b22b
--- /dev/null
@@ -0,0 +1,5 @@
+sonar.projectKey=sample-multiline
+sonar.projectName=Sample Multiline
+sonar.projectVersion=1.0-SNAPSHOT
+sonar.sources=src/main/xoo
+sonar.language=xoo
diff --git a/it/it-projects/shared/xoo-precise-issues/src/main/xoo/sample/Sample.xoo b/it/it-projects/shared/xoo-precise-issues/src/main/xoo/sample/Sample.xoo
new file mode 100644 (file)
index 0000000..56ce099
--- /dev/null
@@ -0,0 +1,16 @@
+package sample;
+
+public class Sample {
+       
+       public Sample(int i) {
+               int j {xoo-start-issue:0}= i++{xoo-end-issue:0};
+       }
+       
+       {xoo-start-issue:1}private String myMethod() {
+               if (foo == bar) {
+                       return "hello";
+               } else {
+                       throw new IllegalStateException();
+               }
+       }{xoo-end-issue:1}
+}
index 6c2d1cd4e5a17caaa15f95c454d9d1e99a85327f..0b2c75db8504899b63b768d36c064bc57c7a9379 100644 (file)
@@ -6,15 +6,15 @@
 package it.analysis;
 
 import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.BuildResult;
 import com.sonar.orchestrator.build.SonarRunner;
 import com.sonar.orchestrator.locator.FileLocation;
 import com.sonar.orchestrator.locator.ResourceLocation;
 import it.Category3Suite;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Rule;
@@ -23,6 +23,13 @@ import org.junit.rules.TemporaryFolder;
 import org.skyscreamer.jsonassert.JSONAssert;
 import util.ItUtils;
 
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class IssueJsonReportTest {
@@ -38,6 +45,69 @@ public class IssueJsonReportTest {
     orchestrator.resetData();
   }
 
+  @Test
+  public void issue_line() throws IOException {
+    orchestrator.getServer().restoreProfile(getResource("one-issue-per-line.xml"));
+    orchestrator.getServer().provisionProject("sample", "xoo-sample");
+    orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line");
+
+    File projectDir = ItUtils.projectDir("shared/xoo-sample");
+    SonarRunner runner = SonarRunner.create(projectDir,
+      "sonar.analysis.mode", "issues",
+      "sonar.verbose", "true",
+      "sonar.report.export.path", "sonar-report.json");
+    BuildResult result = orchestrator.executeBuild(runner);
+    assertThat(ItUtils.countIssuesInJsonReport(result, true)).isEqualTo(17);
+
+    JSONObject obj = ItUtils.getJSONReport(result);
+    JSONArray issues = (JSONArray) obj.get("issues");
+    for (Object issue : issues) {
+      JSONObject jsonIssue = (JSONObject) issue;
+      assertThat(jsonIssue.get("startLine")).isNotNull();
+      assertThat(jsonIssue.get("endLine")).isNotNull();
+
+      assertThat(jsonIssue.get("endLine")).isEqualTo(jsonIssue.get("startLine"));
+
+      assertThat(jsonIssue.get("endOffset")).isNotNull();
+      assertThat(jsonIssue.get("startOffset")).isNotNull();
+    }
+
+    List<Long> lineNumbers = new ArrayList<Long>(16);
+    for (long i = 1L; i < 18; i++) {
+      lineNumbers.add(i);
+    }
+    assertThat(issues).extracting("startLine").containsAll(lineNumbers);
+    assertThat(issues).extracting("endLine").containsAll(lineNumbers);
+  }
+
+  @Test
+  public void precise_issue_location() throws IOException {
+    orchestrator.getServer().restoreProfile(getResource("multiline.xml"));
+    orchestrator.getServer().provisionProject("sample-multiline", "xoo-sample");
+    orchestrator.getServer().associateProjectToQualityProfile("sample-multiline", "xoo", "multiline");
+
+    File projectDir = ItUtils.projectDir("shared/xoo-precise-issues");
+    SonarRunner runner = SonarRunner.create(projectDir,
+      "sonar.analysis.mode", "issues",
+      "sonar.verbose", "true",
+      "sonar.report.export.path", "sonar-report.json");
+    BuildResult result = orchestrator.executeBuild(runner);
+    assertThat(ItUtils.countIssuesInJsonReport(result, true)).isEqualTo(2);
+
+    JSONObject obj = ItUtils.getJSONReport(result);
+    JSONArray issues = (JSONArray) obj.get("issues");
+
+    for (Object i : issues) {
+      JSONObject issue = (JSONObject) i;
+      assertThat(issue.get("startLine")).isIn(6L, 9L);
+      assertThat(issue.get("line")).isIn(6L, 9L);
+      assertThat(issue.get("endLine")).isIn(6L, 15L);
+      assertThat(issue.get("startOffset")).isIn(27L, 20L);
+      assertThat(issue.get("endOffset")).isIn(32L, 2L);
+    }
+
+  }
+
   @Test
   public void test_json_report_no_server_analysis() throws Exception {
     orchestrator.getServer().restoreProfile(getResource("one-issue-per-line.xml"));
index f5ec507b123d781beaee64b10f70c180e156949f..14749d888fd28cdef60e4695280d3c5e75208fec 100644 (file)
@@ -116,11 +116,11 @@ public class IssuesModeTest {
       assertThat(i.status()).isEqualTo("OPEN");
     }
     assertThat(serverIssues).hasSize(17);
-    
+
     // change quality profile
     restoreProfile("with-many-rules.xml");
     orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "with-many-rules");
-    
+
     // do it again, scanning nothing (all files should be unchanged)
     runner = configureRunnerIssues("shared/xoo-sample",
       "sonar.verbose", "true");
@@ -129,7 +129,7 @@ public class IssuesModeTest {
     assertThat(result.getLogs()).contains("'One Issue Per Line' skipped because there is no related file in current project");
     ItUtils.assertIssuesInJsonReport(result, 0, 0, 17);
   }
-  
+
   // SONAR-6931
   @Test
   public void only_scan_changed_files_transitions() throws IOException {
@@ -144,7 +144,7 @@ public class IssuesModeTest {
       assertThat(i.status()).isEqualTo("OPEN");
     }
     assertThat(serverIssues).hasSize(17);
-    
+
     // resolve 2 issues
     IssueClient issueClient = orchestrator.getServer().wsClient("admin", "admin").issueClient();
     issueClient.doTransition(serverIssues.get(0).key(), "wontfix");
@@ -158,7 +158,7 @@ public class IssuesModeTest {
     assertThat(result.getLogs()).contains("'One Issue Per Line' skipped because there is no related file in current project");
     ItUtils.assertIssuesInJsonReport(result, 0, 0, 15);
   }
-  
+
   // SONAR-6931
   @Test
   public void only_scan_changed_files_on_change() throws IOException {
@@ -168,11 +168,11 @@ public class IssuesModeTest {
 
     SonarRunner runner = configureRunner("shared/xoo-sample", "sonar.verbose", "true");
     BuildResult result = orchestrator.executeBuild(runner);
-    
+
     // change QP
     restoreProfile("with-many-rules.xml");
     orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "with-many-rules");
-    
+
     // now change file hash in a temporary location
     File tmpProjectDir = temp.newFolder();
     FileUtils.copyDirectory(ItUtils.projectDir("shared/xoo-sample"), tmpProjectDir);
@@ -192,7 +192,7 @@ public class IssuesModeTest {
     assertThat(result.getLogs()).doesNotContain("'One Issue Per Line' skipped because there is no related file in current project");
     ItUtils.assertIssuesInJsonReport(result, 3, 0, 17);
   }
-  
+
   @Test
   public void non_associated_mode() throws IOException {
     restoreProfile("one-issue-per-line.xml");
@@ -299,8 +299,8 @@ public class IssuesModeTest {
     orchestrator.executeBuild(runner);
 
     // Second run issues mode
-    runner = configureRunnerIssues("shared/xoo-sample", 
-      "sonar.report.export.path", "sonar-report.json", 
+    runner = configureRunnerIssues("shared/xoo-sample",
+      "sonar.report.export.path", "sonar-report.json",
       "sonar.scanAllFiles", "true");
     result = orchestrator.executeBuild(runner);
 
@@ -331,7 +331,7 @@ public class IssuesModeTest {
     restoreProfile("/one-issue-per-line.xml");
 
     // Second issues mode
-    runner = configureRunnerIssues("shared/xoo-sample", 
+    runner = configureRunnerIssues("shared/xoo-sample",
       "sonar.report.export.path", "sonar-report.json",
       "sonar.scanAllFiles", "true");
     result = orchestrator.executeBuild(runner);
diff --git a/it/it-tests/src/test/resources/analysis/IssueJsonReportTest/multiline.xml b/it/it-tests/src/test/resources/analysis/IssueJsonReportTest/multiline.xml
new file mode 100644 (file)
index 0000000..778866e
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?><!-- Generated by Sonar -->
+<profile>
+  <name>multiline</name>
+  <language>xoo</language>
+  <rules>
+    <rule>
+      <repositoryKey>xoo</repositoryKey>
+      <key>MultilineIssue</key>
+      <priority>MAJOR</priority>
+    </rule>
+  </rules>
+</profile>
index 3b632a14ba0f998f0ce2085526b893358b4e9c85..4e1b18df6ee258bed2c5cb0089f839f10d13f23f 100644 (file)
 {
-    "version": "<SONAR_VERSION>",
+    "components": [
+        {
+            "key": "sample"
+        },
+        {
+            "key": "sample:src/main/xoo/sample/Sample.xoo",
+            "moduleKey": "sample",
+            "path": "src/main/xoo/sample/Sample.xoo",
+            "status": "ADDED"
+        },
+        {
+            "key": "sample:src/main/xoo/sample",
+            "moduleKey": "sample",
+            "path": "src/main/xoo/sample"
+        }
+    ],
     "issues": [
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 6,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 2,
+            "endOffset": 0,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 2,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 5,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 6,
+            "endOffset": 14,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 6,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 13,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 1,
+            "endOffset": 15,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 1,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 1,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 5,
+            "endOffset": 23,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 5,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 3,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 8,
+            "endOffset": 1,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 8,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 4,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 9,
+            "endOffset": 28,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 9,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 12,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 7,
+            "endOffset": 2,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 7,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 10,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 4,
+            "endOffset": 1,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 4,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 2,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 11,
+            "endOffset": 2,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 11,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 9,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 3,
+            "endOffset": 21,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 3,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 11,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 13,
+            "endOffset": 0,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 13,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 7,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 12,
+            "endOffset": 1,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 12,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:src/main/xoo/sample/Sample.xoo",
-            "line": 8,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 10,
+            "endOffset": 17,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
-        }
-    ],
-    "components": [
-        {
-            "key": "sample"
-        },
-        {
-            "key": "sample:src/main/xoo/sample",
-            "path": "src/main/xoo/sample",
-            "moduleKey": "sample"
-        },
-        {
-            "key": "sample:src/main/xoo/sample/Sample.xoo",
-            "path": "src/main/xoo/sample/Sample.xoo",
-            "moduleKey": "sample",
-            "status": "ADDED"
+            "severity": "MAJOR",
+            "startLine": 10,
+            "startOffset": 0,
+            "status": "OPEN"
         }
     ],
     "rules": [
         {
             "key": "xoo:OneIssuePerLine",
-            "rule": "OneIssuePerLine",
+            "name": "One Issue Per Line",
             "repository": "xoo",
-            "name": "One Issue Per Line"
+            "rule": "OneIssuePerLine"
         }
     ],
-    "users": [ ]
-
+    "users": [],
+    "version": "<SONAR_VERSION>"
 }
index 53d0bc52c20976a82a7a3f384bcf1c1b84162a36..ad3c0218cdbd90c3b8c30d663e3bea92c5ca7767 100644 (file)
 {
-  "version": "5.2-SNAPSHOT",
-  "issues": [
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 4,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 11,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 2,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 5,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 1,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 15,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 16,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 13,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 9,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 12,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 3,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 8,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 14,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 6,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 10,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "line": 7,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 2,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 12,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 8,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 17,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 19,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 4,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 3,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 21,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 6,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 9,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 18,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 5,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 20,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 15,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 7,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 16,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 13,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 10,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 1,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 14,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "line": 11,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 9,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 10,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 2,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 1,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 8,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 5,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 7,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 3,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 4,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 6,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 12,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "line": 11,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 12,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 5,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 4,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 1,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 8,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 3,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 10,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 6,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 7,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 11,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 2,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "line": 9,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    }
-  ],
-  "components": [
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_a",
-      "path": "module_a"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1",
-      "path": "module_a1"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2",
-      "path": "module_a2"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_b",
-      "path": "module_b"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1",
-      "path": "module_b1"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2",
-      "path": "module_b2"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "path": "src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-      "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1",
-      "status": "SAME"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "path": "src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
-      "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2",
-      "status": "SAME"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "path": "src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
-      "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1",
-      "status": "SAME"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "path": "src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
-      "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2",
-      "status": "SAME"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1",
-      "path": "src/main/xoo/com/sonar/it/samples/modules/a1",
-      "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2",
-      "path": "src/main/xoo/com/sonar/it/samples/modules/a2",
-      "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1",
-      "path": "src/main/xoo/com/sonar/it/samples/modules/b1",
-      "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1"
-    },
-    {
-      "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2",
-      "path": "src/main/xoo/com/sonar/it/samples/modules/b2",
-      "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2"
-    }
-  ],
-  "rules": [
-    {
-      "key": "xoo:OneIssuePerLine",
-      "rule": "OneIssuePerLine",
-      "repository": "xoo",
-      "name": "One Issue Per Line"
-    }
-  ],
-  "users": []
+    "components": [
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a",
+            "path": "module_a"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1",
+            "path": "module_a1"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2",
+            "path": "module_a2"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_b",
+            "path": "module_b"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1",
+            "path": "module_b1"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2",
+            "path": "module_b2"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1",
+            "path": "src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "status": "SAME"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2",
+            "path": "src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "status": "SAME"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1",
+            "path": "src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "status": "SAME"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2",
+            "path": "src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "status": "SAME"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1",
+            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1",
+            "path": "src/main/xoo/com/sonar/it/samples/modules/a1"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2",
+            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2",
+            "path": "src/main/xoo/com/sonar/it/samples/modules/a2"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1",
+            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1",
+            "path": "src/main/xoo/com/sonar/it/samples/modules/b1"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2",
+            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2",
+            "path": "src/main/xoo/com/sonar/it/samples/modules/b2"
+        }
+    ],
+    "issues": [
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 9,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 9,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 9,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 10,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 10,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 10,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 11,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 11,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 11,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 12,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 12,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 12,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 13,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 13,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 13,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 14,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 14,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 14,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 15,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 15,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 15,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 16,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 16,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 16,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 1,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 1,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 1,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 2,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 2,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 2,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 3,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 3,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 3,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 4,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 4,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 4,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 5,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 5,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 5,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 7,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 7,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 7,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 6,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 6,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 6,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 8,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 8,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 8,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 1,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 1,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 1,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 2,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 2,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 2,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 3,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 3,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 3,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 4,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 4,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 4,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 5,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 5,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 5,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 6,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 6,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 6,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 7,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 7,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 7,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 8,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 8,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 8,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 9,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 9,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 9,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 10,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 10,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 10,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 11,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 11,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 11,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 12,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 12,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 12,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 13,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 13,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 13,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 14,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 14,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 14,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 15,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 15,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 15,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 16,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 16,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 16,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 17,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 17,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 17,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 18,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 18,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 18,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 19,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 19,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 19,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 20,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 20,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 20,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a2:src/main/xoo/com/sonar/it/samples/modules/a2/HelloA2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 21,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 21,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 21,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 1,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 1,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 1,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 2,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 2,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 2,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 3,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 3,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 3,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 4,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 4,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 4,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 5,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 5,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 5,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 6,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 6,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 6,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 7,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 7,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 7,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 8,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 8,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 8,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 9,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 9,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 9,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 10,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 10,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 10,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 11,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 11,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 11,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b1:src/main/xoo/com/sonar/it/samples/modules/b1/HelloB1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 12,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 12,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 12,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 1,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 1,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 1,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 2,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 2,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 2,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 3,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 3,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 3,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 4,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 4,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 4,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 5,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 5,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 5,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 6,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 6,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 6,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 7,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 7,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 7,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 8,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 8,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 8,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 9,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 9,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 9,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 10,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 10,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 10,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 12,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 12,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 12,
+            "status": "OPEN"
+        },
+        {
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_b:module_b2:src/main/xoo/com/sonar/it/samples/modules/b2/HelloB2.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 11,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 11,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 11,
+            "status": "OPEN"
+        }
+    ],
+    "rules": [
+        {
+            "key": "xoo:OneIssuePerLine",
+            "name": "One Issue Per Line",
+            "repository": "xoo",
+            "rule": "OneIssuePerLine"
+        }
+    ],
+    "users": [],
+    "version": "<SONAR_VERSION>"
 }
index a7673ec603fcdf7ec7b7b46147178ca9cf74d7b4..aa066bbbf2fdf60170baec6afd06e009e0ce8836 100644 (file)
 {
-    "version": "<SONAR_VERSION>",
+    "components": [
+        {
+            "key": "sample:mybranch"
+        },
+        {
+            "key": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
+            "moduleKey": "sample:mybranch",
+            "path": "src/main/xoo/sample/Sample.xoo",
+            "status": "CHANGED"
+        },
+        {
+            "key": "sample:mybranch:src/main/xoo/sample",
+            "moduleKey": "sample:mybranch",
+            "path": "src/main/xoo/sample"
+        }
+    ],
     "issues": [
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 2,
-            "message": "This issue is generated on each line",
-            "severity": "MAJOR",
-            "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 1,
+            "endOffset": 15,
             "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
-        },
-        {
             "key": "<ISSUE_KEY>",
-            "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 10,
+            "line": 1,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 1,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 13,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 2,
+            "endOffset": 0,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 2,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 2,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 15,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 3,
+            "endOffset": 21,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 3,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 3,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 4,
+            "endOffset": 1,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
             "line": 4,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 4,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 3,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 5,
+            "endOffset": 23,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 5,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 5,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 12,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 6,
+            "endOffset": 14,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 6,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 6,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 11,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 8,
+            "endOffset": 2,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 8,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 8,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 5,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 9,
+            "endOffset": 1,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 9,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 9,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 7,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 10,
+            "endOffset": 28,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 10,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": true,
-            "creationDate": "2013-05-02T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 10,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 9,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 12,
+            "endOffset": 17,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 12,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 12,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 6,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 13,
+            "endOffset": 2,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 13,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 13,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 8,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 14,
+            "endOffset": 1,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 14,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 14,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 1,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 15,
+            "endOffset": 0,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 15,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 15,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "line": 14,
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 11,
+            "endOffset": 28,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
+            "line": 11,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
-        }
-    ],
-    "components": [
-        {
-            "key": "sample:mybranch"
-        },
-        {
-            "key": "sample:mybranch:src/main/xoo/sample",
-            "path": "src/main/xoo/sample",
-            "moduleKey": "sample:mybranch"
+            "severity": "MAJOR",
+            "startLine": 11,
+            "startOffset": 0,
+            "status": "OPEN"
         },
         {
-            "key": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
-            "path": "src/main/xoo/sample/Sample.xoo",
-            "moduleKey": "sample:mybranch",
-            "status": "CHANGED"
+            "component": "sample:mybranch:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 7,
+            "endOffset": 28,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
+            "line": 7,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 7,
+            "startOffset": 0,
+            "status": "OPEN"
         }
     ],
     "rules": [
         {
             "key": "xoo:OneIssuePerLine",
-            "rule": "OneIssuePerLine",
+            "name": "One Issue Per Line",
             "repository": "xoo",
-            "name": "One Issue Per Line"
+            "rule": "OneIssuePerLine"
         }
     ],
-    "users": [ ]
-
+    "users": [],
+    "version": "<SONAR_VERSION>"
 }
index 47b244bd3835f8c35f8a0ffa31dc8f37c45dbc42..6c3aab91f024ec9a39dd2d455672327bab966898 100644 (file)
 {
-  "version": "<SONAR_VERSION>",
-  "issues": [
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 6,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 5,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 13,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 1,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 3,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 4,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 12,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 10,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 2,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 9,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 11,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": true,
-      "creationDate": "2013-05-02T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 7,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": true,
-      "creationDate": "2013-05-02T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 8,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 14,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    },
-    {
-      "key": "<ISSUE_KEY>",
-      "component": "sample:src/main/xoo/sample/Sample.xoo",
-      "line": 15,
-      "message": "This issue is generated on each line",
-      "severity": "MAJOR",
-      "rule": "xoo:OneIssuePerLine",
-      "status": "OPEN",
-      "isNew": false,
-      "creationDate": "2013-05-01T00:00:00+0200"
-    }
-  ],
-  "components": [
-    {
-      "key": "sample"
-    },
-    {
-      "key": "sample:src/main/xoo/sample",
-      "path": "src/main/xoo/sample",
-      "moduleKey": "sample"
-    },
-    {
-      "key": "sample:src/main/xoo/sample/Sample.xoo",
-      "path": "src/main/xoo/sample/Sample.xoo",
-      "moduleKey": "sample",
-      "status": "CHANGED"
-    }
-  ],
-  "rules": [
-    {
-      "key": "xoo:OneIssuePerLine",
-      "rule": "OneIssuePerLine",
-      "repository": "xoo",
-      "name": "One Issue Per Line"
-    }
-  ],
-  "users": []
+    "components": [
+        {
+            "key": "sample"
+        },
+        {
+            "key": "sample:src/main/xoo/sample/Sample.xoo",
+            "moduleKey": "sample",
+            "path": "src/main/xoo/sample/Sample.xoo",
+            "status": "CHANGED"
+        },
+        {
+            "key": "sample:src/main/xoo/sample",
+            "moduleKey": "sample",
+            "path": "src/main/xoo/sample"
+        }
+    ],
+    "issues": [
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 11,
+            "endOffset": 28,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
+            "line": 11,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 11,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-02T00:00:00+0200",
+            "endLine": 7,
+            "endOffset": 28,
+            "isNew": true,
+            "key": "<ISSUE_KEY>",
+            "line": 7,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 7,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 1,
+            "endOffset": 15,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 1,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 1,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 2,
+            "endOffset": 0,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 2,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 2,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 3,
+            "endOffset": 21,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 3,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 3,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 4,
+            "endOffset": 1,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 4,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 4,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 5,
+            "endOffset": 23,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 5,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 5,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 6,
+            "endOffset": 14,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 6,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 6,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 8,
+            "endOffset": 2,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 8,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 8,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 9,
+            "endOffset": 1,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 9,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 9,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 10,
+            "endOffset": 28,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 10,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 10,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 12,
+            "endOffset": 17,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 12,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 12,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 13,
+            "endOffset": 2,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 13,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 13,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 14,
+            "endOffset": 1,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 14,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 14,
+            "startOffset": 0,
+            "status": "OPEN"
+        },
+        {
+            "component": "sample:src/main/xoo/sample/Sample.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 15,
+            "endOffset": 0,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 15,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 15,
+            "startOffset": 0,
+            "status": "OPEN"
+        }
+    ],
+    "rules": [
+        {
+            "key": "xoo:OneIssuePerLine",
+            "name": "One Issue Per Line",
+            "repository": "xoo",
+            "rule": "OneIssuePerLine"
+        }
+    ],
+    "users": [],
+    "version": "<SONAR_VERSION>"
 }
index cc979a77420890f8aeb7ef0cce484ef92809f330..84a68c4d5a4b482c17d338175dc33b13a68413da 100644 (file)
 {
-
-    "version": "<SONAR_VERSION>",
+    "components": [
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1",
+            "path": "src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "status": "SAME"
+        },
+        {
+            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1",
+            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1",
+            "path": "src/main/xoo/com/sonar/it/samples/modules/a1"
+        }
+    ],
     "issues": [
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 4,
-            "message": "This issue is generated on each line",
-            "severity": "MAJOR",
-            "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 1,
             "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
-        },
-        {
             "key": "<ISSUE_KEY>",
-            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 7,
+            "line": 1,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 1,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 6,
-            "message": "This issue is generated on each line",
-            "severity": "MAJOR",
-            "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 2,
             "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
-        },
-        {
             "key": "<ISSUE_KEY>",
-            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 1,
+            "line": 2,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 2,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 8,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 3,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 3,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 3,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 15,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 4,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 4,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 4,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 14,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 5,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 5,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 5,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 10,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 6,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 6,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 6,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 3,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 7,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 7,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 7,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 2,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 8,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 8,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 8,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 16,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 9,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 9,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 9,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 9,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 10,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 10,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 10,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 5,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 11,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 11,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 11,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 12,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
             "line": 12,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 12,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 13,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
             "line": 13,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
+            "severity": "MAJOR",
+            "startLine": 13,
+            "status": "OPEN"
         },
         {
-            "key": "<ISSUE_KEY>",
             "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "line": 11,
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 14,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 14,
             "message": "This issue is generated on each line",
-            "severity": "MAJOR",
             "rule": "xoo:OneIssuePerLine",
-            "status": "OPEN",
-            "isNew": false,
-            "creationDate": "2013-05-01T00:00:00+0200"
-        }
-    ],
-    "components": [
-        {
-            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1"
+            "severity": "MAJOR",
+            "startLine": 14,
+            "status": "OPEN"
         },
         {
-            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1",
-            "path": "src/main/xoo/com/sonar/it/samples/modules/a1",
-            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1"
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 15,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 15,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 15,
+            "status": "OPEN"
         },
         {
-            "key": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "path": "src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
-            "moduleKey": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1",
-            "status": "SAME"
+            "component": "com.sonarsource.it.samples:multi-modules-sample:module_a:module_a1:src/main/xoo/com/sonar/it/samples/modules/a1/HelloA1.xoo",
+            "creationDate": "2013-05-01T00:00:00+0200",
+            "endLine": 16,
+            "isNew": false,
+            "key": "<ISSUE_KEY>",
+            "line": 16,
+            "message": "This issue is generated on each line",
+            "rule": "xoo:OneIssuePerLine",
+            "severity": "MAJOR",
+            "startLine": 16,
+            "status": "OPEN"
         }
     ],
     "rules": [
         {
             "key": "xoo:OneIssuePerLine",
-            "rule": "OneIssuePerLine",
+            "name": "One Issue Per Line",
             "repository": "xoo",
-            "name": "One Issue Per Line"
+            "rule": "OneIssuePerLine"
         }
     ],
-    "users": [ ]
-
+    "users": [],
+    "version": "<SONAR_VERSION>"
 }
index b2bf0fd57aa9434dea943920aa87f02985a2711b..3ccee7b3deee3c41bc73ec1fff583e3f0d41bbf3 100644 (file)
@@ -21,11 +21,19 @@ package org.sonar.batch.bootstrapper;
 
 public interface IssueListener {
   void handle(Issue issue);
-  
+
   class Issue {
+    /** @since 5.3 */
+    private Integer startLine;
+    /** @since 5.3 */
+    private Integer startLineOffset;
+    /** @since 5.3 */
+    private Integer endLine;
+    /** @since 5.3 */
+    private Integer endLineOffset;
+
     private String key;
     private String componentKey;
-    private Integer line;
     private String message;
     private String ruleKey;
     private String ruleName;
@@ -60,12 +68,36 @@ public interface IssueListener {
       this.componentKey = componentKey;
     }
 
-    public Integer getLine() {
-      return line;
+    public Integer getStartLine() {
+      return startLine;
+    }
+
+    public void setStartLine(Integer startLine) {
+      this.startLine = startLine;
+    }
+
+    public Integer getStartLineOffset() {
+      return startLineOffset;
+    }
+
+    public void setStartLineOffset(Integer startLineOffset) {
+      this.startLineOffset = startLineOffset;
+    }
+
+    public Integer getEndLine() {
+      return endLine;
+    }
+
+    public void setEndLine(Integer endLine) {
+      this.endLine = endLine;
+    }
+
+    public Integer getEndLineOffset() {
+      return endLineOffset;
     }
 
-    public void setLine(Integer line) {
-      this.line = line;
+    public void setEndLineOffset(Integer endLineOffset) {
+      this.endLineOffset = endLineOffset;
     }
 
     public String getMessage() {
index 8f7342e05e5848beda055e3187bee2dccf2e6206..92bbc63fa65e02470aec3c4b2f6b74c23c06e280 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.issue;
 
-import org.apache.commons.lang.StringUtils;
+import org.sonar.batch.issue.tracking.TrackedIssue;
 
+import org.apache.commons.lang.StringUtils;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.batch.rule.Rule;
 import org.sonar.api.batch.rule.Rules;
@@ -33,7 +34,6 @@ import java.util.Set;
 
 import org.sonar.batch.repository.user.UserRepositoryLoader;
 import org.sonar.batch.bootstrapper.IssueListener;
-import org.sonar.core.issue.DefaultIssue;
 
 public class DefaultIssueCallback implements IssueCallback {
   private final IssueCache issues;
@@ -65,37 +65,40 @@ public class DefaultIssueCallback implements IssueCallback {
       return;
     }
 
-    for (DefaultIssue issue : issues.all()) {
+    for (TrackedIssue issue : issues.all()) {
       collectInfo(issue);
     }
 
     getUsers();
 
-    for (DefaultIssue issue : issues.all()) {
+    for (TrackedIssue issue : issues.all()) {
       IssueListener.Issue newIssue = new IssueListener.Issue();
       newIssue.setAssigneeLogin(issue.assignee());
       newIssue.setAssigneeName(getAssigneeName(issue.assignee()));
       newIssue.setComponentKey(issue.componentKey());
       newIssue.setKey(issue.key());
-      newIssue.setLine(issue.getLine());
-      newIssue.setMessage(issue.getMessage());
+      newIssue.setMessage(issue.message());
       newIssue.setNew(issue.isNew());
       newIssue.setResolution(issue.resolution());
-      newIssue.setRuleKey(issue.getRuleKey().toString());
-      newIssue.setRuleName(getRuleName(issue.getRuleKey()));
+      newIssue.setRuleKey(issue.ruleKey().toString());
+      newIssue.setRuleName(getRuleName(issue.ruleKey()));
       newIssue.setSeverity(issue.severity());
       newIssue.setStatus(issue.status());
+      newIssue.setStartLine(issue.startLine());
+      newIssue.setStartLineOffset(issue.startLineOffset());
+      newIssue.setEndLine(issue.endLine());
+      newIssue.setEndLineOffset(issue.endLineOffset());
 
       listener.handle(newIssue);
     }
   }
 
-  private void collectInfo(DefaultIssue issue) {
+  private void collectInfo(TrackedIssue issue) {
     if (!StringUtils.isEmpty(issue.assignee())) {
       userLoginNames.add(issue.assignee());
     }
-    if (issue.getRuleKey() != null) {
-      ruleKeys.add(issue.getRuleKey());
+    if (issue.ruleKey() != null) {
+      ruleKeys.add(issue.ruleKey());
     }
   }
 
index 9f869ca95ef0d8d1424dddbd25cb5e6d6626cfd9..244eb01b1bf84a42db8f9515f87880fbaae1fd0c 100644 (file)
  */
 package org.sonar.batch.issue;
 
+import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.issue.ProjectIssues;
-import org.sonar.core.issue.DefaultIssue;
+import org.sonar.batch.issue.tracking.TrackedIssue;
 
 import javax.annotation.Nullable;
 
@@ -41,15 +42,19 @@ public class DefaultProjectIssues implements ProjectIssues {
 
   @Override
   public Iterable<Issue> issues() {
-    return (Iterable) Iterables.filter(cache.all(), new ResolvedPredicate(false));
+    return Iterables.transform(
+      Iterables.filter(cache.all(), new ResolvedPredicate(false)),
+      new IssueTransformer());
   }
 
   @Override
   public Iterable<Issue> resolvedIssues() {
-    return (Iterable) Iterables.filter(cache.all(), new ResolvedPredicate(true));
+    return Iterables.transform(
+      Iterables.filter(cache.all(), new ResolvedPredicate(true)),
+      new IssueTransformer());
   }
 
-  private static class ResolvedPredicate implements Predicate<DefaultIssue> {
+  private static class ResolvedPredicate implements Predicate<TrackedIssue> {
     private final boolean resolved;
 
     private ResolvedPredicate(boolean resolved) {
@@ -57,11 +62,18 @@ public class DefaultProjectIssues implements ProjectIssues {
     }
 
     @Override
-    public boolean apply(@Nullable DefaultIssue issue) {
+    public boolean apply(@Nullable TrackedIssue issue) {
       if (issue != null) {
         return resolved ? (issue.resolution() != null) : (issue.resolution() == null);
       }
       return false;
     }
   }
+
+  private static class IssueTransformer implements Function<TrackedIssue, Issue> {
+    @Override
+    public Issue apply(TrackedIssue issue) {
+      return new TrackedIssueAdapter(issue);
+    }
+  }
 }
index 52a29fb74831b81d26beb9a37c66e4382e4c007a..af80f5f73583d335edb1c26d49e008aa1c373151 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.issue;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import org.sonar.api.batch.BatchSide;
-import org.sonar.core.issue.DefaultIssue;
 import org.sonar.batch.index.Cache;
 import org.sonar.batch.index.Caches;
 
@@ -33,17 +34,17 @@ import java.util.Collection;
 public class IssueCache {
 
   // component key -> issue key -> issue
-  private final Cache<DefaultIssue> cache;
+  private final Cache<TrackedIssue> cache;
 
   public IssueCache(Caches caches) {
     cache = caches.createCache("issues");
   }
 
-  public Iterable<DefaultIssue> byComponent(String componentKey) {
+  public Iterable<TrackedIssue> byComponent(String componentKey) {
     return cache.values(componentKey);
   }
 
-  public Iterable<DefaultIssue> all() {
+  public Iterable<TrackedIssue> all() {
     return cache.values();
   }
 
@@ -51,7 +52,7 @@ public class IssueCache {
     return cache.keySet();
   }
 
-  public IssueCache put(DefaultIssue issue) {
+  public IssueCache put(TrackedIssue issue) {
     cache.put(issue.componentKey(), issue.key(), issue);
     return this;
   }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/IssueTransformer.java b/sonar-batch/src/main/java/org/sonar/batch/issue/IssueTransformer.java
new file mode 100644 (file)
index 0000000..65bd924
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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 com.google.common.base.Preconditions;
+
+import org.sonar.core.util.Uuids;
+import org.sonar.api.issue.Issue;
+import org.sonar.batch.protocol.output.BatchReport.TextRange;
+import org.sonar.core.component.ComponentKeys;
+
+import java.util.Date;
+
+import org.sonar.batch.issue.tracking.TrackedIssue;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.batch.index.BatchComponent;
+import org.sonar.batch.protocol.output.BatchReport;
+
+public class IssueTransformer {
+  private IssueTransformer() {
+    // static only
+  }
+
+  public static TrackedIssue toTrackedIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue serverIssue) {
+    TrackedIssue issue = new TrackedIssue();
+    issue.setKey(serverIssue.getKey());
+    issue.setStatus(serverIssue.getStatus());
+    issue.setResolution(serverIssue.hasResolution() ? serverIssue.getResolution() : null);
+    issue.setMessage(serverIssue.hasMsg() ? serverIssue.getMsg() : null);
+    issue.setStartLine(serverIssue.hasLine() ? serverIssue.getLine() : null);
+    issue.setEndLine(serverIssue.hasLine() ? serverIssue.getLine() : null);
+    issue.setSeverity(serverIssue.getSeverity().name());
+    issue.setAssignee(serverIssue.hasAssigneeLogin() ? serverIssue.getAssigneeLogin() : null);
+    issue.setComponentKey(ComponentKeys.createEffectiveKey(serverIssue.getModuleKey(), serverIssue.hasPath() ? serverIssue.getPath() : null));
+    issue.setCreationDate(new Date(serverIssue.getCreationDate()));
+    issue.setRuleKey(RuleKey.of(serverIssue.getRuleRepository(), serverIssue.getRuleKey()));
+    issue.setNew(false);
+    return issue;
+  }
+
+  public static void close(TrackedIssue issue) {
+    issue.setStatus(Issue.STATUS_CLOSED);
+    issue.setStartLine(null);
+    issue.setEndLine(null);
+    issue.setResolution(Issue.RESOLUTION_FIXED);
+  }
+
+  public static void resolveRemove(TrackedIssue issue) {
+    issue.setStatus(Issue.STATUS_CLOSED);
+    issue.setStartLine(null);
+    issue.setEndLine(null);
+    issue.setResolution(Issue.RESOLUTION_REMOVED);
+  }
+
+  public static TrackedIssue toTrackedIssue(BatchComponent component, BatchReport.Issue rawIssue) {
+    RuleKey ruleKey = RuleKey.of(rawIssue.getRuleRepository(), rawIssue.getRuleKey());
+
+    Preconditions.checkNotNull(component.key(), "Component key must be set");
+    Preconditions.checkNotNull(ruleKey, "Rule key must be set");
+
+    TrackedIssue issue = new TrackedIssue();
+
+    issue.setKey(Uuids.create());
+    issue.setComponentKey(component.key());
+    issue.setRuleKey(ruleKey);
+    issue.setEffortToFix(rawIssue.hasEffortToFix() ? rawIssue.getEffortToFix() : null);
+    issue.setSeverity(rawIssue.getSeverity().name());
+    issue.setMessage(rawIssue.hasMsg() ? rawIssue.getMsg() : null);
+    issue.setResolution(null);
+    issue.setStatus(Issue.STATUS_OPEN);
+    issue.setNew(true);
+
+    if (rawIssue.hasTextRange()) {
+      TextRange r = rawIssue.getTextRange();
+
+      issue.setStartLine(r.hasStartLine() ? rawIssue.getTextRange().getStartLine() : null);
+      issue.setStartLineOffset(r.hasStartOffset() ? r.getStartOffset() : null);
+      issue.setEndLine(r.hasEndLine() ? r.getEndLine() : issue.startLine());
+      issue.setEndLineOffset(r.hasEndOffset() ? r.getEndOffset() : null);
+    }
+
+    return issue;
+  }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/TrackedIssueAdapter.java b/sonar-batch/src/main/java/org/sonar/batch/issue/TrackedIssueAdapter.java
new file mode 100644 (file)
index 0000000..a10a139
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * 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.api.issue.IssueComment;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.utils.Duration;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.sonar.batch.issue.tracking.TrackedIssue;
+import org.sonar.api.issue.Issue;
+
+public class TrackedIssueAdapter implements Issue {
+  private TrackedIssue issue;
+
+  public TrackedIssueAdapter(TrackedIssue issue) {
+    this.issue = issue;
+  }
+
+  @Override
+  public String key() {
+    return issue.key();
+  }
+
+  @Override
+  public String componentKey() {
+    return issue.componentKey();
+  }
+
+  @Override
+  public RuleKey ruleKey() {
+    return issue.ruleKey();
+  }
+
+  @Override
+  public String severity() {
+    return issue.severity();
+  }
+
+  @Override
+  public String message() {
+    return issue.message();
+  }
+
+  @Override
+  public Integer line() {
+    return issue.startLine();
+  }
+
+  @Override
+  public Double effortToFix() {
+    return issue.effortToFix();
+  }
+
+  @Override
+  public String status() {
+    return issue.status();
+  }
+
+  @Override
+  public String resolution() {
+    return issue.resolution();
+  }
+
+  @Override
+  public String reporter() {
+    return issue.reporter();
+  }
+
+  @Override
+  public String assignee() {
+    return issue.assignee();
+  }
+
+  @Override
+  public boolean isNew() {
+    return issue.isNew();
+  }
+
+  @Override
+  public Map<String, String> attributes() {
+    return new HashMap<>();
+  }
+
+  @Override
+  public Date creationDate() {
+    return null;
+  }
+
+  @Override
+  public String language() {
+    return null;
+  }
+
+  @Override
+  public Date updateDate() {
+    return null;
+  }
+
+  @Override
+  public Date closeDate() {
+    return null;
+  }
+
+  @Override
+  public String attribute(String key) {
+    return null;
+  }
+
+  @Override
+  public String authorLogin() {
+    return null;
+  }
+
+  @Override
+  public String actionPlanKey() {
+    return null;
+  }
+
+  @Override
+  public List<IssueComment> comments() {
+    return new ArrayList<>();
+  }
+
+  @Override
+  public Duration debt() {
+    return null;
+  }
+
+  @Override
+  public String projectKey() {
+    return null;
+  }
+
+  @Override
+  public String projectUuid() {
+    return null;
+  }
+
+  @Override
+  public String componentUuid() {
+    return null;
+  }
+
+  @Override
+  public Collection<String> tags() {
+    return new ArrayList<>();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o == null || !(o instanceof Issue)) {
+      return false;
+    }
+    Issue that = (Issue) o;
+    return !(issue.key() != null ? !issue.key().equals(that.key()) : (that.key() != null));
+  }
+
+  @Override
+  public int hashCode() {
+    return issue.key() != null ? issue.key().hashCode() : 0;
+  }
+}
index 6dcbb685209a48b8ca3507b848574c21770ebbba..ff79165cff32887f1f54c903af929568453c7a7e 100644 (file)
  */
 package org.sonar.batch.issue.tracking;
 
+import org.sonar.batch.issue.IssueTransformer;
+
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
+
 import java.util.Date;
 import java.util.List;
 import java.util.Set;
+
 import javax.annotation.Nullable;
+
 import org.sonar.api.batch.BatchSide;
 import org.sonar.api.resources.Project;
-import org.sonar.api.rule.RuleKey;
 import org.sonar.batch.index.BatchComponent;
 import org.sonar.batch.index.BatchComponentCache;
 import org.sonar.batch.issue.IssueCache;
 import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.batch.protocol.output.BatchReportReader;
 import org.sonar.batch.report.ReportPublisher;
-import org.sonar.core.issue.DefaultIssue;
-import org.sonar.core.issue.IssueChangeContext;
-import org.sonar.core.issue.workflow.IssueWorkflow;
 import org.sonar.core.util.CloseableIterator;
 
 @BatchSide
 public class IssueTransition {
   private final IssueCache issueCache;
-  private final IssueWorkflow workflow;
-  private final IssueChangeContext changeContext;
   private final BatchComponentCache componentCache;
   private final ReportPublisher reportPublisher;
   private final Date analysisDate;
   @Nullable
   private final LocalIssueTracking localIssueTracking;
 
-  public IssueTransition(BatchComponentCache componentCache, IssueCache issueCache, IssueWorkflow workflow, ReportPublisher reportPublisher,
+  public IssueTransition(BatchComponentCache componentCache, IssueCache issueCache, ReportPublisher reportPublisher,
     @Nullable LocalIssueTracking localIssueTracking) {
     this.componentCache = componentCache;
     this.issueCache = issueCache;
-    this.workflow = workflow;
     this.reportPublisher = reportPublisher;
     this.localIssueTracking = localIssueTracking;
     this.analysisDate = ((Project) componentCache.getRoot().resource()).getAnalysisDate();
-    this.changeContext = IssueChangeContext.createScan(analysisDate);
   }
 
-  public IssueTransition(BatchComponentCache componentCache, IssueCache issueCache, IssueWorkflow workflow, ReportPublisher reportPublisher) {
-    this(componentCache, issueCache, workflow, reportPublisher, null);
+  public IssueTransition(BatchComponentCache componentCache, IssueCache issueCache, ReportPublisher reportPublisher) {
+    this(componentCache, issueCache, reportPublisher, null);
   }
 
   public void execute() {
@@ -88,7 +85,7 @@ public class IssueTransition {
       throw new IllegalStateException("Can't read issues for " + component.key(), e);
     }
 
-    List<DefaultIssue> trackedIssues;
+    List<TrackedIssue> trackedIssues;
     if (localIssueTracking != null) {
       trackedIssues = localIssueTracking.trackIssues(component, rawIssues);
     } else {
@@ -98,32 +95,19 @@ public class IssueTransition {
     // Unmatched raw issues = new issues
     addUnmatchedRawIssues(component, rawIssues, trackedIssues);
 
-    for (DefaultIssue issue : trackedIssues) {
-      workflow.doAutomaticTransition(issue, changeContext);
+    for (TrackedIssue issue : trackedIssues) {
       issueCache.put(issue);
     }
   }
-  
-  private void addUnmatchedRawIssues(BatchComponent component, Set<org.sonar.batch.protocol.output.BatchReport.Issue> rawIssues, List<DefaultIssue> trackedIssues) {
+
+  private void addUnmatchedRawIssues(BatchComponent component, Set<org.sonar.batch.protocol.output.BatchReport.Issue> rawIssues, List<TrackedIssue> trackedIssues) {
     for (BatchReport.Issue rawIssue : rawIssues) {
 
-      DefaultIssue tracked = toTracked(component, rawIssue);
-      tracked.setNew(true);
+      TrackedIssue tracked = IssueTransformer.toTrackedIssue(component, rawIssue);
       tracked.setCreationDate(analysisDate);
 
       trackedIssues.add(tracked);
     }
   }
 
-  private DefaultIssue toTracked(BatchComponent component, BatchReport.Issue rawIssue) {
-    return new org.sonar.core.issue.DefaultIssueBuilder()
-      .componentKey(component.key())
-      .projectKey("unused")
-      .ruleKey(RuleKey.of(rawIssue.getRuleRepository(), rawIssue.getRuleKey()))
-      .effortToFix(rawIssue.hasEffortToFix() ? rawIssue.getEffortToFix() : null)
-      .line(rawIssue.hasLine() ? rawIssue.getLine() : null)
-      .message(rawIssue.hasMsg() ? rawIssue.getMsg() : null)
-      .severity(rawIssue.getSeverity().name())
-      .build();
-  }
 }
index 8c77079f5f6e75759b89b4dc38fa1e4594915c2a..77c8ee7b0cd6bb07a4e15425daadc10431c47bf5 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.issue.tracking;
 
-import org.sonar.api.batch.fs.InputFile.Status;
+import org.sonar.batch.issue.IssueTransformer;
 
+import org.sonar.api.batch.fs.InputFile.Status;
 import org.sonar.batch.analysis.DefaultAnalysisMode;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Lists;
@@ -38,42 +39,27 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.rule.ActiveRule;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.issue.Issue;
-import org.sonar.api.resources.Project;
 import org.sonar.api.resources.ResourceUtils;
-import org.sonar.api.rule.RuleKey;
 import org.sonar.batch.index.BatchComponent;
-import org.sonar.batch.index.BatchComponentCache;
 import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.batch.report.ReportPublisher;
 import org.sonar.batch.repository.ProjectRepositories;
-import org.sonar.core.component.ComponentKeys;
-import org.sonar.core.issue.DefaultIssue;
-import org.sonar.core.issue.IssueChangeContext;
-import org.sonar.core.issue.IssueUpdater;
 
 @BatchSide
 public class LocalIssueTracking {
   private final IssueTracking tracking;
   private final ServerLineHashesLoader lastLineHashes;
-  private final IssueUpdater updater;
-  private final IssueChangeContext changeContext;
   private final ActiveRules activeRules;
   private final ServerIssueRepository serverIssueRepository;
-  private final Date analysisDate;
   private final DefaultAnalysisMode mode;
 
   private boolean hasServerAnalysis;
 
-  public LocalIssueTracking(BatchComponentCache resourceCache, IssueTracking tracking, ServerLineHashesLoader lastLineHashes, IssueUpdater updater,
-    ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, ReportPublisher reportPublisher,
-    DefaultAnalysisMode mode) {
+  public LocalIssueTracking(IssueTracking tracking, ServerLineHashesLoader lastLineHashes,
+    ActiveRules activeRules, ServerIssueRepository serverIssueRepository, ProjectRepositories projectRepositories, DefaultAnalysisMode mode) {
     this.tracking = tracking;
     this.lastLineHashes = lastLineHashes;
-    this.updater = updater;
     this.serverIssueRepository = serverIssueRepository;
     this.mode = mode;
-    this.analysisDate = ((Project) resourceCache.getRoot().resource()).getAnalysisDate();
-    this.changeContext = IssueChangeContext.createScan(analysisDate);
     this.activeRules = activeRules;
     this.hasServerAnalysis = projectRepositories.lastAnalysisDate() != null;
   }
@@ -84,8 +70,8 @@ public class LocalIssueTracking {
     }
   }
 
-  public List<DefaultIssue> trackIssues(BatchComponent component, Set<BatchReport.Issue> rawIssues) {
-    List<DefaultIssue> trackedIssues = Lists.newArrayList();
+  public List<TrackedIssue> trackIssues(BatchComponent component, Set<BatchReport.Issue> rawIssues) {
+    List<TrackedIssue> trackedIssues = Lists.newArrayList();
     if (hasServerAnalysis) {
       // all the issues that are not closed in db before starting this module scan, including manual issues
       Collection<ServerIssue> serverIssues = loadServerIssues(component);
@@ -124,33 +110,23 @@ public class LocalIssueTracking {
     return false;
   }
 
-  private void copyServerIssues(Collection<ServerIssue> serverIssues, List<DefaultIssue> trackedIssues) {
+  private void copyServerIssues(Collection<ServerIssue> serverIssues, List<TrackedIssue> trackedIssues) {
     for (ServerIssue serverIssue : serverIssues) {
       org.sonar.batch.protocol.input.BatchInput.ServerIssue unmatchedPreviousIssue = ((ServerIssueFromWs) serverIssue).getDto();
-      DefaultIssue unmatched = toUnmatchedIssue(unmatchedPreviousIssue);
+      TrackedIssue unmatched = IssueTransformer.toTrackedIssue(unmatchedPreviousIssue);
 
       ActiveRule activeRule = activeRules.find(unmatched.ruleKey());
       unmatched.setNew(false);
 
-      boolean isRemovedRule = activeRule == null;
-      unmatched.setBeingClosed(isRemovedRule);
-      unmatched.setOnDisabledRule(isRemovedRule);
+      if (activeRule == null) {
+        // rule removed
+        IssueTransformer.resolveRemove(unmatched);
+      }
+
       trackedIssues.add(unmatched);
     }
   }
 
-  private DefaultIssue toTracked(BatchComponent component, BatchReport.Issue rawIssue) {
-    return new org.sonar.core.issue.DefaultIssueBuilder()
-      .componentKey(component.key())
-      .projectKey("unused")
-      .ruleKey(RuleKey.of(rawIssue.getRuleRepository(), rawIssue.getRuleKey()))
-      .effortToFix(rawIssue.hasEffortToFix() ? rawIssue.getEffortToFix() : null)
-      .line(rawIssue.hasLine() ? rawIssue.getLine() : null)
-      .message(rawIssue.hasMsg() ? rawIssue.getMsg() : null)
-      .severity(rawIssue.getSeverity().name())
-      .build();
-  }
-
   @CheckForNull
   private SourceHashHolder loadSourceHashes(BatchComponent component) {
     SourceHashHolder sourceHashHolder = null;
@@ -173,20 +149,18 @@ public class LocalIssueTracking {
   }
 
   @VisibleForTesting
-  protected void mergeMatched(BatchComponent component, IssueTrackingResult result, List<DefaultIssue> trackedIssues, Collection<BatchReport.Issue> rawIssues) {
+  protected void mergeMatched(BatchComponent component, IssueTrackingResult result, List<TrackedIssue> trackedIssues, Collection<BatchReport.Issue> rawIssues) {
     for (BatchReport.Issue rawIssue : result.matched()) {
       rawIssues.remove(rawIssue);
       org.sonar.batch.protocol.input.BatchInput.ServerIssue ref = ((ServerIssueFromWs) result.matching(rawIssue)).getDto();
 
-      DefaultIssue tracked = toTracked(component, rawIssue);
+      TrackedIssue tracked = IssueTransformer.toTrackedIssue(component, rawIssue);
 
       // invariant fields
       tracked.setKey(ref.getKey());
 
       // non-persisted fields
       tracked.setNew(false);
-      tracked.setBeingClosed(false);
-      tracked.setOnDisabledRule(false);
 
       // fields to update with old values
       tracked.setResolution(ref.hasResolution() ? ref.getResolution() : null);
@@ -202,10 +176,10 @@ public class LocalIssueTracking {
     }
   }
 
-  private void addUnmatchedFromServer(Collection<ServerIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) {
+  private void addUnmatchedFromServer(Collection<ServerIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<TrackedIssue> issues) {
     for (ServerIssue unmatchedIssue : unmatchedIssues) {
       org.sonar.batch.protocol.input.BatchInput.ServerIssue unmatchedPreviousIssue = ((ServerIssueFromWs) unmatchedIssue).getDto();
-      DefaultIssue unmatched = toUnmatchedIssue(unmatchedPreviousIssue);
+      TrackedIssue unmatched = IssueTransformer.toTrackedIssue(unmatchedPreviousIssue);
       if (unmatchedIssue.ruleKey().isManual() && !Issue.STATUS_CLOSED.equals(unmatchedPreviousIssue.getStatus())) {
         relocateManualIssue(unmatched, unmatchedIssue, sourceHashHolder);
       }
@@ -214,46 +188,29 @@ public class LocalIssueTracking {
     }
   }
 
-  private void addIssuesOnDeletedComponents(Collection<DefaultIssue> issues) {
+  private void addIssuesOnDeletedComponents(Collection<TrackedIssue> issues) {
     for (org.sonar.batch.protocol.input.BatchInput.ServerIssue previous : serverIssueRepository.issuesOnMissingComponents()) {
-      DefaultIssue dead = toUnmatchedIssue(previous);
+      TrackedIssue dead = IssueTransformer.toTrackedIssue(previous);
       updateUnmatchedIssue(dead, true);
       issues.add(dead);
     }
   }
 
-  private DefaultIssue toUnmatchedIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue serverIssue) {
-    DefaultIssue issue = new DefaultIssue();
-    issue.setKey(serverIssue.getKey());
-    issue.setStatus(serverIssue.getStatus());
-    issue.setResolution(serverIssue.hasResolution() ? serverIssue.getResolution() : null);
-    issue.setMessage(serverIssue.hasMsg() ? serverIssue.getMsg() : null);
-    issue.setLine(serverIssue.hasLine() ? serverIssue.getLine() : null);
-    issue.setSeverity(serverIssue.getSeverity().name());
-    issue.setAssignee(serverIssue.hasAssigneeLogin() ? serverIssue.getAssigneeLogin() : null);
-    issue.setComponentKey(ComponentKeys.createEffectiveKey(serverIssue.getModuleKey(), serverIssue.hasPath() ? serverIssue.getPath() : null));
-    issue.setManualSeverity(serverIssue.getManualSeverity());
-    issue.setCreationDate(new Date(serverIssue.getCreationDate()));
-    issue.setRuleKey(RuleKey.of(serverIssue.getRuleRepository(), serverIssue.getRuleKey()));
-    issue.setNew(false);
-    return issue;
-  }
-
-  private void updateUnmatchedIssue(DefaultIssue issue, boolean forceEndOfLife) {
+  private void updateUnmatchedIssue(TrackedIssue issue, boolean forceEndOfLife) {
     ActiveRule activeRule = activeRules.find(issue.ruleKey());
     issue.setNew(false);
 
     boolean manualIssue = issue.ruleKey().isManual();
     boolean isRemovedRule = activeRule == null;
-    if (manualIssue) {
-      issue.setBeingClosed(forceEndOfLife || isRemovedRule);
-    } else {
-      issue.setBeingClosed(true);
+
+    if (isRemovedRule) {
+      IssueTransformer.resolveRemove(issue);
+    } else if (forceEndOfLife || !manualIssue) {
+      IssueTransformer.close(issue);
     }
-    issue.setOnDisabledRule(isRemovedRule);
   }
 
-  private void relocateManualIssue(DefaultIssue newIssue, ServerIssue oldIssue, SourceHashHolder sourceHashHolder) {
+  private static void relocateManualIssue(TrackedIssue newIssue, ServerIssue oldIssue, SourceHashHolder sourceHashHolder) {
     Integer previousLine = oldIssue.line();
     if (previousLine == null) {
       return;
@@ -262,17 +219,12 @@ public class LocalIssueTracking {
     Collection<Integer> newLinesWithSameHash = sourceHashHolder.getNewLinesMatching(previousLine);
     if (newLinesWithSameHash.isEmpty()) {
       if (previousLine > sourceHashHolder.getHashedSource().length()) {
-        newIssue.setLine(null);
-        updater.setStatus(newIssue, Issue.STATUS_CLOSED, changeContext);
-        updater.setResolution(newIssue, Issue.RESOLUTION_REMOVED, changeContext);
-        updater.setPastLine(newIssue, previousLine);
-        updater.setPastMessage(newIssue, oldIssue.message(), changeContext);
+        IssueTransformer.resolveRemove(newIssue);
       }
     } else if (newLinesWithSameHash.size() == 1) {
       Integer newLine = newLinesWithSameHash.iterator().next();
-      newIssue.setLine(newLine);
-      updater.setPastLine(newIssue, previousLine);
-      updater.setPastMessage(newIssue, oldIssue.message(), changeContext);
+      newIssue.setStartLine(newLine);
+      newIssue.setEndLine(newLine);
     }
   }
 }
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/TrackedIssue.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/TrackedIssue.java
new file mode 100644 (file)
index 0000000..480d055
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * 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.tracking;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import org.sonar.api.rule.RuleKey;
+
+public class TrackedIssue implements Serializable {
+  private static final long serialVersionUID = -1755017079070964287L;
+
+  private RuleKey ruleKey;
+  private String key;
+  private String severity;
+  private Integer startLine;
+  private Integer startLineOffset;
+  private Integer endLine;
+  private Integer endLineOffset;
+  private Double effortToFix;
+  private boolean isNew;
+  private Date creationDate;
+  private String resolution;
+  private String status;
+  private String assignee;
+  private String reporter;
+  private String componentKey;
+  private String message;
+
+  public String message() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  public String componentKey() {
+    return componentKey;
+  }
+
+  public void setComponentKey(String componentKey) {
+    this.componentKey = componentKey;
+  }
+
+  public String key() {
+    return key;
+  }
+
+  public Integer startLine() {
+    return startLine;
+  }
+
+  public void setStartLine(Integer startLine) {
+    this.startLine = startLine;
+  }
+
+  public Integer startLineOffset() {
+    return startLineOffset;
+  }
+
+  public void setStartLineOffset(Integer startLineOffset) {
+    this.startLineOffset = startLineOffset;
+  }
+
+  public Integer endLine() {
+    return endLine;
+  }
+
+  public void setEndLine(Integer endLine) {
+    this.endLine = endLine;
+  }
+
+  public Integer endLineOffset() {
+    return endLineOffset;
+  }
+
+  public void setEndLineOffset(Integer endLineOffset) {
+    this.endLineOffset = endLineOffset;
+  }
+
+  public void setKey(String key) {
+    this.key = key;
+  }
+
+  public String assignee() {
+    return assignee;
+  }
+
+  public void setAssignee(String assignee) {
+    this.assignee = assignee;
+  }
+
+  public String reporter() {
+    return reporter;
+  }
+
+  public void setReporter(String reporter) {
+    this.reporter = reporter;
+  }
+
+  public String resolution() {
+    return resolution;
+  }
+
+  public void setResolution(String resolution) {
+    this.resolution = resolution;
+  }
+
+  public String status() {
+    return status;
+  }
+
+  public void setStatus(String status) {
+    this.status = status;
+  }
+
+  public RuleKey ruleKey() {
+    return ruleKey;
+  }
+
+  public String severity() {
+    return severity;
+  }
+
+  public Double effortToFix() {
+    return effortToFix;
+  }
+
+  public Date getCreationDate() {
+    return creationDate;
+  }
+
+  public boolean isNew() {
+    return isNew;
+  }
+
+  public void setNew(boolean isNew) {
+    this.isNew = isNew;
+  }
+
+  public Date creationDate() {
+    return creationDate;
+  }
+
+  public void setCreationDate(Date creationDate) {
+    this.creationDate = creationDate;
+  }
+
+  public void setRuleKey(RuleKey ruleKey) {
+    this.ruleKey = ruleKey;
+  }
+
+  public void setSeverity(String severity) {
+    this.severity = severity;
+  }
+
+  public void setEffortToFix(Double effortToFix) {
+    this.effortToFix = effortToFix;
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((key == null) ? 0 : key.hashCode());
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == null) {
+      return false;
+    }
+    if (getClass() != obj.getClass()) {
+      return false;
+    }
+    TrackedIssue other = (TrackedIssue) obj;
+    if (key == null) {
+      if (other.key != null) {
+        return false;
+      }
+    } else if (!key.equals(other.key)) {
+      return false;
+    }
+    return true;
+  }
+
+}
index 49c7f95736b8adf66e0397ee8e571207ee66fee6..2254fa0798fd83c051c5887f3b31809886c1ac73 100644 (file)
  */
 package org.sonar.batch.mediumtest;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Lists;
+
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -28,8 +31,10 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
+
 import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -42,7 +47,6 @@ import org.sonar.api.batch.fs.TextRange;
 import org.sonar.api.batch.fs.internal.DefaultInputDir;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.sensor.highlighting.TypeOfText;
-import org.sonar.api.issue.Issue;
 import org.sonar.batch.issue.IssueCache;
 import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.batch.protocol.output.BatchReport.Component;
@@ -53,14 +57,13 @@ import org.sonar.batch.report.BatchReportUtils;
 import org.sonar.batch.report.ReportPublisher;
 import org.sonar.batch.scan.ProjectScanContainer;
 import org.sonar.batch.scan.filesystem.InputPathCache;
-import org.sonar.core.issue.DefaultIssue;
 import org.sonar.core.util.CloseableIterator;
 
 public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver {
 
   private static final Logger LOG = LoggerFactory.getLogger(TaskResult.class);
 
-  private List<Issue> issues = new ArrayList<>();
+  private List<TrackedIssue> issues = new ArrayList<>();
   private Map<String, InputFile> inputFiles = new HashMap<>();
   private Map<String, Component> reportComponents = new HashMap<>();
   private Map<String, InputDir> inputDirs = new HashMap<>();
@@ -69,7 +72,7 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver {
   @Override
   public void scanTaskCompleted(ProjectScanContainer container) {
     LOG.info("Store analysis results in memory for later assertions in medium test");
-    for (DefaultIssue issue : container.getComponentByType(IssueCache.class).all()) {
+    for (TrackedIssue issue : container.getComponentByType(IssueCache.class).all()) {
       issues.add(issue);
     }
 
@@ -112,7 +115,7 @@ public class TaskResult implements org.sonar.batch.mediumtest.ScanTaskObserver {
     }
   }
 
-  public List<Issue> trackedIssues() {
+  public List<TrackedIssue> trackedIssues() {
     return issues;
   }
 
index 38787dea74cae37ce9be34ebeeff46de52b696b4..de4ba05f3a122eef5198068deed899cd672fee42 100644 (file)
  */
 package org.sonar.batch.postjob;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
+
 import javax.annotation.Nullable;
+
 import org.sonar.api.batch.AnalysisMode;
 import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.postjob.PostJobContext;
@@ -33,7 +37,6 @@ import org.sonar.api.rule.RuleKey;
 import org.sonar.batch.index.BatchComponent;
 import org.sonar.batch.index.BatchComponentCache;
 import org.sonar.batch.issue.IssueCache;
-import org.sonar.core.issue.DefaultIssue;
 
 public class DefaultPostJobContext implements PostJobContext {
 
@@ -61,29 +64,19 @@ public class DefaultPostJobContext implements PostJobContext {
 
   @Override
   public Iterable<Issue> issues() {
-    return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(false)), new Function<DefaultIssue, Issue>() {
-      @Override
-      public Issue apply(DefaultIssue input) {
-        return new DefaultIssueWrapper(input);
-      }
-    });
+    return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(false)), new IssueTransformer());
   }
 
   @Override
   public Iterable<Issue> resolvedIssues() {
-    return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(true)), new Function<DefaultIssue, Issue>() {
-      @Override
-      public Issue apply(DefaultIssue input) {
-        return new DefaultIssueWrapper(input);
-      }
-    });
+    return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(true)), new IssueTransformer());
   }
 
   private class DefaultIssueWrapper implements Issue {
 
-    private final DefaultIssue wrapped;
+    private final TrackedIssue wrapped;
 
-    public DefaultIssueWrapper(DefaultIssue wrapped) {
+    public DefaultIssueWrapper(TrackedIssue wrapped) {
       this.wrapped = wrapped;
     }
 
@@ -110,7 +103,7 @@ public class DefaultPostJobContext implements PostJobContext {
 
     @Override
     public Integer line() {
-      return wrapped.line();
+      return wrapped.startLine();
     }
 
     @Override
@@ -133,10 +126,16 @@ public class DefaultPostJobContext implements PostJobContext {
     public boolean isNew() {
       return wrapped.isNew();
     }
+  }
 
+  private class IssueTransformer implements Function<TrackedIssue, Issue> {
+    @Override
+    public Issue apply(TrackedIssue input) {
+      return new DefaultIssueWrapper(input);
+    }
   }
 
-  private static class ResolvedPredicate implements Predicate<DefaultIssue> {
+  private static class ResolvedPredicate implements Predicate<TrackedIssue> {
     private final boolean resolved;
 
     private ResolvedPredicate(boolean resolved) {
@@ -144,7 +143,7 @@ public class DefaultPostJobContext implements PostJobContext {
     }
 
     @Override
-    public boolean apply(@Nullable DefaultIssue issue) {
+    public boolean apply(@Nullable TrackedIssue issue) {
       if (issue != null) {
         return resolved ? issue.resolution() != null : issue.resolution() == null;
       }
index 7b605d2b9b03c3d66304665264f5518675ed1011..55a10b6fd25538d96e727e6351bd4907d50dde9a 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.batch.scan;
 
+import org.sonar.batch.issue.DefaultProjectIssues;
+
 import com.google.common.annotations.VisibleForTesting;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.InstantiationStrategy;
@@ -47,7 +49,6 @@ import org.sonar.batch.index.BatchComponentCache;
 import org.sonar.batch.index.Caches;
 import org.sonar.batch.index.DefaultIndex;
 import org.sonar.batch.issue.DefaultIssueCallback;
-import org.sonar.batch.issue.DefaultProjectIssues;
 import org.sonar.batch.issue.IssueCache;
 import org.sonar.batch.issue.tracking.DefaultServerLineHashesLoader;
 import org.sonar.batch.issue.tracking.IssueTransition;
@@ -91,9 +92,7 @@ import org.sonar.batch.scan.measure.MeasureCache;
 import org.sonar.batch.source.CodeColorizers;
 import org.sonar.batch.test.TestPlanBuilder;
 import org.sonar.batch.test.TestableBuilder;
-import org.sonar.core.issue.IssueUpdater;
 import org.sonar.core.issue.workflow.FunctionExecutor;
-import org.sonar.core.issue.workflow.IssueWorkflow;
 import org.sonar.core.platform.ComponentContainer;
 
 public class ProjectScanContainer extends ComponentContainer {
@@ -166,9 +165,7 @@ public class ProjectScanContainer extends ComponentContainer {
       new QualityProfileProvider(),
 
       // issues
-      IssueUpdater.class,
       FunctionExecutor.class,
-      IssueWorkflow.class,
       IssueCache.class,
       DefaultProjectIssues.class,
       IssueTransition.class,
index 0627d986451e78401ca4812861681a4deb96b3c4..50752b9900f4e1ebfdaeebd7c4e776698f3ede50 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.batch.scan.report;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import com.google.common.annotations.VisibleForTesting;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.Properties;
@@ -30,7 +32,6 @@ import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.batch.issue.IssueCache;
 import org.sonar.batch.scan.filesystem.InputPathCache;
-import org.sonar.core.issue.DefaultIssue;
 
 @Properties({
   @Property(key = ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, name = "Enable console report", description = "Set this to true to generate a report in console output",
@@ -65,7 +66,7 @@ public class ConsoleReport implements Reporter {
     int newMinorIssues = 0;
     int newInfoIssues = 0;
 
-    public void process(DefaultIssue issue) {
+    public void process(TrackedIssue issue) {
       if (issue.isNew()) {
         totalNewIssues++;
         switch (issue.severity()) {
@@ -100,7 +101,7 @@ public class ConsoleReport implements Reporter {
     if (settings.getBoolean(CONSOLE_REPORT_ENABLED_KEY)) {
       Report r = new Report();
       r.setNoFile(!inputPathCache.allFiles().iterator().hasNext());
-      for (DefaultIssue issue : issueCache.all()) {
+      for (TrackedIssue issue : issueCache.all()) {
         r.process(issue);
       }
       printReport(r);
index 63abaace82e713bbcb15cf28d78a49e0cb618562..8a36447dabac348cbcfacfc0b982d474a6b09f9e 100644 (file)
  */
 package org.sonar.batch.scan.report;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import com.google.common.collect.Maps;
+
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+
 import org.sonar.api.batch.rule.Rule;
-import org.sonar.api.issue.Issue;
 import org.sonar.api.rules.RulePriority;
 import org.sonar.batch.index.BatchComponent;
 
@@ -78,16 +81,16 @@ public class IssuesReport {
     return new ArrayList<>(resourceReportsByResource.keySet());
   }
 
-  public void addIssueOnResource(BatchComponent resource, Issue issue, Rule rule, RulePriority severity) {
+  public void addIssueOnResource(BatchComponent resource, TrackedIssue issue, Rule rule, RulePriority severity) {
     addResource(resource);
     getSummary().addIssue(issue, rule, severity);
     resourceReportsByResource.get(resource).addIssue(issue, rule, RulePriority.valueOf(issue.severity()));
   }
 
-  public void addResolvedIssueOnResource(BatchComponent resource, Issue issue, Rule rule, RulePriority severity) {
+  public void addResolvedIssueOnResource(BatchComponent resource, TrackedIssue issue, Rule rule, RulePriority severity) {
     addResource(resource);
     getSummary().addResolvedIssue(issue, rule, severity);
-    resourceReportsByResource.get(resource).addResolvedIssue(issue, rule, RulePriority.valueOf(issue.severity()));
+    resourceReportsByResource.get(resource).addResolvedIssue(rule, RulePriority.valueOf(issue.severity()));
   }
 
   private void addResource(BatchComponent resource) {
index ec89540927afd00c1558aa545149360ce1bb59d4..87db0a3bc69c44b25900f96a9a87d03cc7694d3b 100644 (file)
  */
 package org.sonar.batch.scan.report;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import javax.annotation.CheckForNull;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.BatchSide;
 import org.sonar.api.batch.rule.Rule;
 import org.sonar.api.batch.rule.Rules;
-import org.sonar.api.issue.Issue;
 import org.sonar.api.resources.Project;
 import org.sonar.api.rules.RulePriority;
 import org.sonar.batch.DefaultProjectTree;
@@ -33,7 +35,6 @@ import org.sonar.batch.index.BatchComponent;
 import org.sonar.batch.index.BatchComponentCache;
 import org.sonar.batch.issue.IssueCache;
 import org.sonar.batch.scan.filesystem.InputPathCache;
-import org.sonar.core.issue.DefaultIssue;
 
 @BatchSide
 public class IssuesReportBuilder {
@@ -66,8 +67,8 @@ public class IssuesReportBuilder {
     return issuesReport;
   }
 
-  private void processIssues(IssuesReport issuesReport, Iterable<DefaultIssue> issues) {
-    for (Issue issue : issues) {
+  private void processIssues(IssuesReport issuesReport, Iterable<TrackedIssue> issues) {
+    for (TrackedIssue issue : issues) {
       Rule rule = findRule(issue);
       RulePriority severity = RulePriority.valueOf(issue.severity());
       BatchComponent resource = resourceCache.get(issue.componentKey());
@@ -82,7 +83,7 @@ public class IssuesReportBuilder {
     }
   }
 
-  private static boolean validate(Issue issue, Rule rule, BatchComponent resource) {
+  private static boolean validate(TrackedIssue issue, Rule rule, BatchComponent resource) {
     if (rule == null) {
       LOG.warn("Unknow rule for issue {}", issue);
       return false;
@@ -95,7 +96,7 @@ public class IssuesReportBuilder {
   }
 
   @CheckForNull
-  private Rule findRule(Issue issue) {
+  private Rule findRule(TrackedIssue issue) {
     return rules.find(issue.ruleKey());
   }
 
index 68c2f5f94db9990315e6becb412e023411cc301e..847d4ceb2565cf43e66a729a8297b2c0bb795b28 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.scan.report;
 
-import org.sonar.batch.protocol.input.BatchInput.User;
+import org.sonar.batch.issue.tracking.TrackedIssue;
 
+import org.sonar.batch.protocol.input.BatchInput.User;
 import com.google.common.annotations.VisibleForTesting;
 
 import java.io.BufferedWriter;
@@ -57,7 +58,6 @@ import org.sonar.batch.issue.IssueCache;
 import org.sonar.batch.protocol.input.BatchInput;
 import org.sonar.batch.repository.user.UserRepositoryLoader;
 import org.sonar.batch.scan.filesystem.InputPathCache;
-import org.sonar.core.issue.DefaultIssue;
 import static com.google.common.collect.Sets.newHashSet;
 
 @Properties({
@@ -133,13 +133,17 @@ public class JSONReport implements Reporter {
 
   private void writeJsonIssues(JsonWriter json, Set<RuleKey> ruleKeys, Set<String> logins) throws IOException {
     json.name("issues").beginArray();
-    for (DefaultIssue issue : getIssues()) {
+    for (TrackedIssue issue : getIssues()) {
       if (issue.resolution() == null) {
         json
           .beginObject()
           .prop("key", issue.key())
           .prop("component", issue.componentKey())
-          .prop("line", issue.line())
+          .prop("line", issue.startLine())
+          .prop("startLine", issue.startLine())
+          .prop("startOffset", issue.startLineOffset())
+          .prop("endLine", issue.endLine())
+          .prop("endOffset", issue.endLineOffset())
           .prop("message", issue.message())
           .prop("severity", issue.severity())
           .prop("rule", issue.ruleKey().toString())
@@ -240,7 +244,7 @@ public class JSONReport implements Reporter {
   }
 
   @VisibleForTesting
-  Iterable<DefaultIssue> getIssues() {
+  Iterable<TrackedIssue> getIssues() {
     return issueCache.all();
   }
 }
index 2ebb4a2f9a941db43e5931c08265ed4377a19f67..45af927e0bd4cbf668916bd234f8b728b2fc1cd0 100644 (file)
  */
 package org.sonar.batch.scan.report;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import com.google.common.collect.Maps;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+
 import org.sonar.api.batch.rule.Rule;
-import org.sonar.api.issue.Issue;
 import org.sonar.api.rules.RulePriority;
 
 public class ReportSummary {
@@ -40,7 +43,7 @@ public class ReportSummary {
     return total;
   }
 
-  public void addIssue(Issue issue, Rule rule, RulePriority severity) {
+  public void addIssue(TrackedIssue issue, Rule rule, RulePriority severity) {
     ReportRuleKey reportRuleKey = new ReportRuleKey(rule, severity);
     initMaps(reportRuleKey);
     ruleReportByRuleKey.get(reportRuleKey).getTotal().incrementCountInCurrentAnalysis();
@@ -63,7 +66,7 @@ public class ReportSummary {
     return totalByRuleKey;
   }
 
-  public void addResolvedIssue(Issue issue, Rule rule, RulePriority severity) {
+  public void addResolvedIssue(TrackedIssue issue, Rule rule, RulePriority severity) {
     ReportRuleKey reportRuleKey = new ReportRuleKey(rule, severity);
     initMaps(reportRuleKey);
     total.incrementResolvedIssuesCount();
index 2a6135e5c17bc30fc71c9426ae0736d5e237cbeb..a088d8361bb997962c9f505b6238753964df51a5 100644 (file)
  */
 package org.sonar.batch.scan.report;
 
-import org.sonar.api.batch.rule.Rule;
+import org.sonar.batch.issue.tracking.TrackedIssue;
 
+import org.sonar.api.batch.rule.Rule;
 import com.google.common.collect.Maps;
-import org.sonar.api.issue.Issue;
 import org.sonar.api.rules.RulePriority;
 import org.sonar.batch.index.BatchComponent;
 
@@ -37,9 +37,9 @@ public final class ResourceReport {
   private final IssueVariation total = new IssueVariation();
   private final Map<ReportRuleKey, RuleReport> ruleReportByRuleKey = Maps.newHashMap();
 
-  private List<Issue> issues = new ArrayList<>();
-  private Map<Integer, List<Issue>> issuesPerLine = Maps.newHashMap();
-  private Map<Integer, List<Issue>> newIssuesPerLine = Maps.newHashMap();
+  private List<TrackedIssue> issues = new ArrayList<>();
+  private Map<Integer, List<TrackedIssue>> issuesPerLine = Maps.newHashMap();
+  private Map<Integer, List<TrackedIssue>> newIssuesPerLine = Maps.newHashMap();
   private Map<Rule, AtomicInteger> issuesByRule = Maps.newHashMap();
   private Map<RulePriority, AtomicInteger> issuesBySeverity = Maps.newHashMap();
 
@@ -63,15 +63,15 @@ public final class ResourceReport {
     return total;
   }
 
-  public List<Issue> getIssues() {
+  public List<TrackedIssue> getIssues() {
     return issues;
   }
 
-  public Map<Integer, List<Issue>> getIssuesPerLine() {
+  public Map<Integer, List<TrackedIssue>> getIssuesPerLine() {
     return issuesPerLine;
   }
 
-  public List<Issue> getIssuesAtLine(int lineId, boolean all) {
+  public List<TrackedIssue> getIssuesAtLine(int lineId, boolean all) {
     if (all) {
       if (issuesPerLine.containsKey(lineId)) {
         return issuesPerLine.get(lineId);
@@ -82,14 +82,14 @@ public final class ResourceReport {
     return Collections.emptyList();
   }
 
-  public void addIssue(Issue issue, Rule rule, RulePriority severity) {
+  public void addIssue(TrackedIssue issue, Rule rule, RulePriority severity) {
     ReportRuleKey reportRuleKey = new ReportRuleKey(rule, severity);
     initMaps(reportRuleKey);
     issues.add(issue);
-    Integer line = issue.line();
+    Integer line = issue.startLine();
     line = line != null ? line : 0;
     if (!issuesPerLine.containsKey(line)) {
-      issuesPerLine.put(line, new ArrayList<Issue>());
+      issuesPerLine.put(line, new ArrayList<TrackedIssue>());
     }
     issuesPerLine.get(line).add(issue);
     if (!issuesByRule.containsKey(rule)) {
@@ -104,7 +104,7 @@ public final class ResourceReport {
     total.incrementCountInCurrentAnalysis();
     if (issue.isNew()) {
       if (!newIssuesPerLine.containsKey(line)) {
-        newIssuesPerLine.put(line, new ArrayList<Issue>());
+        newIssuesPerLine.put(line, new ArrayList<TrackedIssue>());
       }
       newIssuesPerLine.get(line).add(issue);
       total.incrementNewIssuesCount();
@@ -112,7 +112,7 @@ public final class ResourceReport {
     }
   }
 
-  public void addResolvedIssue(Issue issue, Rule rule, RulePriority severity) {
+  public void addResolvedIssue(Rule rule, RulePriority severity) {
     ReportRuleKey reportRuleKey = new ReportRuleKey(rule, severity);
     initMaps(reportRuleKey);
     total.incrementResolvedIssuesCount();
@@ -139,10 +139,10 @@ public final class ResourceReport {
 
   private boolean hasIssues(Integer lineId, boolean all) {
     if (all) {
-      List<Issue> issuesAtLine = issuesPerLine.get(lineId);
+      List<TrackedIssue> issuesAtLine = issuesPerLine.get(lineId);
       return issuesAtLine != null && !issuesAtLine.isEmpty();
     }
-    List<Issue> newIssuesAtLine = newIssuesPerLine.get(lineId);
+    List<TrackedIssue> newIssuesAtLine = newIssuesPerLine.get(lineId);
     return newIssuesAtLine != null && !newIssuesAtLine.isEmpty();
   }
 
index 3c5827f43e8b7a001037cf3e07e90293cb158f4d..28101545651c7db9f2c77e8b75c06b4643cba1bc 100644 (file)
@@ -13,7 +13,7 @@
         <#assign issues=resourceReport.getIssues()>
         <#list issues as issue>
           <#if complete || issue.isNew()>
-          {'k': '${issue.key()}', 'r': 'R${issue.ruleKey()}', 'l': ${(issue.line()!0)?c}, 'new': ${issue.isNew()?string}, 's': '${issue.severity()?lower_case}'}<#if issue_has_next>,</#if>
+          {'k': '${issue.key()}', 'r': 'R${issue.ruleKey()}', 'l': ${(issue.startLine()!0)?c}, 'new': ${issue.isNew()?string}, 's': '${issue.severity()?lower_case}'}<#if issue_has_next>,</#if>
           </#if>
         </#list>
       ]
index de1b59fed368a59cf02d8b7bdb60371e76d563b3..ea8ca35d8319c08012b70b4909d687ee4f98eb1e 100644 (file)
@@ -21,6 +21,9 @@ package org.sonar.batch.issue;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import org.sonar.api.batch.rule.Rule;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.batch.bootstrapper.IssueListener.Issue;
@@ -32,13 +35,11 @@ import org.sonar.batch.repository.user.UserRepositoryLoader;
 import org.sonar.batch.bootstrapper.IssueListener;
 import org.junit.Before;
 import com.google.common.collect.ImmutableList;
-import org.sonar.core.issue.DefaultIssue;
 
 import java.util.LinkedList;
 import java.util.List;
 
 import static org.mockito.Matchers.any;
-
 import static org.assertj.core.api.Assertions.assertThat;
 import org.junit.Test;
 
@@ -50,14 +51,14 @@ public class DefaultIssueCallbackTest {
   @Mock
   private Rules rules;
 
-  private DefaultIssue issue;
+  private TrackedIssue issue;
 
   @Before
   public void setUp() {
     MockitoAnnotations.initMocks(this);
 
     RuleKey ruleKey = RuleKey.of("repo", "key");
-    issue = new DefaultIssue();
+    issue = new TrackedIssue();
     issue.setKey("key");
     issue.setAssignee("user");
     issue.setRuleKey(ruleKey);
index 99c6d5f710017c5c68e73e617d8355147208687b..c4af828349bad7ca2842517c8b834e607977097b 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.batch.issue;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import com.google.common.collect.Lists;
 import org.junit.Test;
 import org.sonar.api.issue.Issue;
@@ -49,9 +51,9 @@ public class DefaultProjectIssuesTest {
 
     DefaultIssue issueOnRoot = new DefaultIssue().setKey("4").setRuleKey(SQUID_RULE_KEY).setSeverity(Severity.CRITICAL).setComponentKey("org.apache:struts");
     DefaultIssue issueInRoot = new DefaultIssue().setKey("5").setRuleKey(SQUID_RULE_KEY).setSeverity(Severity.CRITICAL).setComponentKey("org.apache:struts:FileInRoot");
-    when(cache.all()).thenReturn(Arrays.<DefaultIssue> asList(
-      issueOnRoot, issueInRoot,
-      issueOnModule, issueInModule, resolvedIssueInModule
+    when(cache.all()).thenReturn(Arrays.<TrackedIssue>asList(
+      toTrackedIssue(issueOnRoot), toTrackedIssue(issueInRoot),
+      toTrackedIssue(issueOnModule), toTrackedIssue(issueInModule), toTrackedIssue(resolvedIssueInModule)
       ));
 
     // unresolved issues
@@ -61,4 +63,16 @@ public class DefaultProjectIssuesTest {
     List<Issue> resolvedIssues = Lists.newArrayList(projectIssues.resolvedIssues());
     assertThat(resolvedIssues).containsOnly(resolvedIssueInModule);
   }
+
+  private TrackedIssue toTrackedIssue(DefaultIssue issue) {
+    TrackedIssue trackedIssue = new TrackedIssue();
+
+    trackedIssue.setKey(issue.key());
+    trackedIssue.setRuleKey(issue.ruleKey());
+    trackedIssue.setComponentKey(issue.componentKey());
+    trackedIssue.setSeverity(issue.severity());
+    trackedIssue.setResolution(issue.resolution());
+
+    return trackedIssue;
+  }
 }
index 18e90aff802c50751af56b265187c59b9acc3090..7d752856ff613a0fb02c80078f8a45b5d9fe90e9 100644 (file)
  */
 package org.sonar.batch.issue;
 
-import org.sonar.batch.index.AbstractCachesTest;
+import org.sonar.batch.issue.tracking.TrackedIssue;
 
+import org.sonar.batch.index.AbstractCachesTest;
 import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
 import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.core.issue.DefaultIssue;
 import org.sonar.api.rule.Severity;
 
 import javax.annotation.Nullable;
 
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 
@@ -42,28 +40,29 @@ public class IssueCacheTest extends AbstractCachesTest {
   @Test
   public void should_add_new_issue() {
     IssueCache cache = new IssueCache(caches);
-    DefaultIssue issue1 = new DefaultIssue().setKey("111").setComponentKey("org.struts.Action");
-    DefaultIssue issue2 = new DefaultIssue().setKey("222").setComponentKey("org.struts.Action");
-    DefaultIssue issue3 = new DefaultIssue().setKey("333").setComponentKey("org.struts.Filter").setTags(Arrays.asList("foo", "bar"));
+    TrackedIssue issue1 = createIssue("111", "org.struts.Action", null);
+    TrackedIssue issue2 = createIssue("222", "org.struts.Action", null);
+    TrackedIssue issue3 = createIssue("333", "org.struts.Filter", null);
+    issue3.setAssignee("foo");
     cache.put(issue1).put(issue2).put(issue3);
 
     assertThat(issueKeys(cache.byComponent("org.struts.Action"))).containsOnly("111", "222");
     assertThat(issueKeys(cache.byComponent("org.struts.Filter"))).containsOnly("333");
-    assertThat(cache.byComponent("org.struts.Filter").iterator().next().tags()).containsOnly("foo", "bar");
+    assertThat(cache.byComponent("org.struts.Filter").iterator().next().assignee()).isEqualTo("foo");
   }
 
   @Test
   public void should_update_existing_issue() {
     IssueCache cache = new IssueCache(caches);
-    DefaultIssue issue = new DefaultIssue().setKey("111").setComponentKey("org.struts.Action").setSeverity(Severity.BLOCKER);
+    TrackedIssue issue = createIssue("111", "org.struts.Action", Severity.BLOCKER);
     cache.put(issue);
 
     issue.setSeverity(Severity.MINOR);
     cache.put(issue);
 
-    List<DefaultIssue> issues = ImmutableList.copyOf(cache.byComponent("org.struts.Action"));
+    List<TrackedIssue> issues = ImmutableList.copyOf(cache.byComponent("org.struts.Action"));
     assertThat(issues).hasSize(1);
-    Issue reloaded = issues.iterator().next();
+    TrackedIssue reloaded = issues.iterator().next();
     assertThat(reloaded.key()).isEqualTo("111");
     assertThat(reloaded.severity()).isEqualTo(Severity.MINOR);
   }
@@ -71,20 +70,29 @@ public class IssueCacheTest extends AbstractCachesTest {
   @Test
   public void should_get_all_issues() {
     IssueCache cache = new IssueCache(caches);
-    DefaultIssue issue1 = new DefaultIssue().setKey("111").setComponentKey("org.struts.Action").setSeverity(Severity.BLOCKER);
-    DefaultIssue issue2 = new DefaultIssue().setKey("222").setComponentKey("org.struts.Filter").setSeverity(Severity.INFO);
+    TrackedIssue issue1 = createIssue("111", "org.struts.Action", Severity.BLOCKER);
+    TrackedIssue issue2 = createIssue("222", "org.struts.Filter", Severity.INFO);
     cache.put(issue1).put(issue2);
 
-    List<DefaultIssue> issues = ImmutableList.copyOf(cache.all());
+    List<TrackedIssue> issues = ImmutableList.copyOf(cache.all());
     assertThat(issues).containsOnly(issue1, issue2);
   }
 
-  private Collection<String> issueKeys(Iterable<DefaultIssue> issues) {
-    return Collections2.transform(ImmutableList.copyOf(issues), new Function<DefaultIssue, String>() {
+  private Collection<String> issueKeys(Iterable<TrackedIssue> issues) {
+    return Collections2.transform(ImmutableList.copyOf(issues), new Function<TrackedIssue, String>() {
       @Override
-      public String apply(@Nullable DefaultIssue issue) {
+      public String apply(@Nullable TrackedIssue issue) {
         return issue.key();
       }
     });
   }
+
+  private TrackedIssue createIssue(String key, String componentKey, String severity) {
+    TrackedIssue issue = new TrackedIssue();
+    issue.setKey(key);
+    issue.setComponentKey(componentKey);
+    issue.setSeverity(severity);
+
+    return issue;
+  }
 }
index 2226796cc4049195c62f169db6e8be4ebcb9ad2e..80c35ec128659e08957bdb61eb8b738d15f13572 100644 (file)
@@ -88,6 +88,10 @@ public class IssuesMediumTest {
 
     List<Issue> issues = result.issuesFor(result.inputFile("xources/hello/HelloJava.xoo"));
     assertThat(issues).hasSize(8 /* lines */);
+
+    Issue issue = issues.get(0);
+    assertThat(issue.getTextRange().getStartLine()).isEqualTo(issue.getLine());
+    assertThat(issue.getTextRange().getEndLine()).isEqualTo(issue.getLine());
   }
 
   @Test
index 586bba47896a78de85fd1d68dd32d763b99a916c..42c092dc5369cbab980bcb65c422539e9470e268 100644 (file)
@@ -19,8 +19,9 @@
  */
 package org.sonar.batch.mediumtest.issuesmode;
 
-import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.sonar.batch.issue.tracking.TrackedIssue;
 
+import org.apache.commons.io.filefilter.FileFilterUtils;
 import org.apache.commons.io.FileUtils;
 import org.sonar.xoo.rule.XooRulesDefinition;
 import com.google.common.collect.ImmutableMap;
@@ -76,6 +77,10 @@ public class EmptyFileTest {
       .property("sonar.xoo.internalKey", "my/internal/key")
       .start();
 
+    for(TrackedIssue i : result.trackedIssues()) {
+      System.out.println(i.startLine() + " " + i.message());
+    }
+    
     assertThat(result.trackedIssues()).hasSize(11);
   }
 
index 0e0ee39b9e36ba291f843cb47882fb80184060b5..5916ff1a81ead03da24ada3bff9f05b6aaef4b05 100644 (file)
  */
 package org.sonar.batch.mediumtest.issuesmode;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import com.google.common.collect.ImmutableMap;
+
 import java.io.File;
 import java.io.IOException;
 import java.text.ParseException;
@@ -27,6 +30,7 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
+
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.filefilter.FileFilterUtils;
@@ -35,7 +39,6 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.CoreProperties;
-import org.sonar.api.issue.Issue;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.batch.bootstrapper.IssueListener;
 import org.sonar.batch.mediumtest.BatchMediumTester;
@@ -45,7 +48,6 @@ import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
 import org.sonar.batch.scan.report.ConsoleReport;
 import org.sonar.xoo.XooPlugin;
 import org.sonar.xoo.rule.XooRulesDefinition;
-
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class IssueModeAndReportsMediumTest {
@@ -153,9 +155,10 @@ public class IssueModeAndReportsMediumTest {
     int newIssues = 0;
     int openIssues = 0;
     int resolvedIssue = 0;
-    for (Issue issue : result.trackedIssues()) {
+    for (TrackedIssue issue : result.trackedIssues()) {
       System.out
-        .println(issue.message() + " " + issue.key() + " " + issue.ruleKey() + " " + issue.isNew() + " " + issue.resolution() + " " + issue.componentKey() + " " + issue.line());
+        .println(issue.message() + " " + issue.key() + " " + issue.ruleKey() + " " + issue.isNew() + " " + issue.resolution() + " " + issue.componentKey() + " "
+          + issue.startLine());
       if (issue.isNew()) {
         newIssues++;
       } else if (issue.resolution() != null) {
index 2141351e8522120d1056dd3138673df5b390d875..855d6b6c986ccc099a93544009696b50bc8dafd8 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.batch.mediumtest.issuesmode;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import org.assertj.core.api.Condition;
 import com.google.common.io.Resources;
 import org.sonar.batch.repository.FileData;
@@ -37,7 +39,6 @@ import org.sonar.xoo.rule.XooRulesDefinition;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.utils.log.LogTester;
 import org.junit.Test;
-import org.sonar.api.issue.Issue;
 import org.sonar.batch.mediumtest.TaskResult;
 
 import java.io.File;
@@ -178,9 +179,9 @@ public class ScanOnlyChangedTest {
   }
 
   private static void assertNumberIssuesOnFile(TaskResult result, final String fileNameEndsWith, int issues) {
-    assertThat(result.trackedIssues()).haveExactly(issues, new Condition<Issue>() {
+    assertThat(result.trackedIssues()).haveExactly(issues, new Condition<TrackedIssue>() {
       @Override
-      public boolean matches(Issue value) {
+      public boolean matches(TrackedIssue value) {
         return value.componentKey().endsWith(fileNameEndsWith);
       }
     });
@@ -190,9 +191,10 @@ public class ScanOnlyChangedTest {
     int newIssues = 0;
     int openIssues = 0;
     int resolvedIssue = 0;
-    for (Issue issue : result.trackedIssues()) {
+    for (TrackedIssue issue : result.trackedIssues()) {
       System.out
-        .println(issue.message() + " " + issue.key() + " " + issue.ruleKey() + " " + issue.isNew() + " " + issue.resolution() + " " + issue.componentKey() + " " + issue.line());
+        .println(issue.message() + " " + issue.key() + " " + issue.ruleKey() + " " + issue.isNew() + " " + issue.resolution() + " " + issue.componentKey() + " "
+          + issue.startLine());
       if (issue.isNew()) {
         newIssues++;
       } else if (issue.resolution() != null) {
index a350ba4a9524a08d79218434b67623aad71b5559..fa3fb23b031c17847337aab7c572e748ad96bce9 100644 (file)
  */
 package org.sonar.batch.postjob;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import java.util.Arrays;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.batch.AnalysisMode;
@@ -30,8 +33,6 @@ import org.sonar.api.config.Settings;
 import org.sonar.api.resources.File;
 import org.sonar.batch.index.BatchComponentCache;
 import org.sonar.batch.issue.IssueCache;
-import org.sonar.core.issue.DefaultIssue;
-
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -58,12 +59,12 @@ public class DefaultPostJobContextTest {
     assertThat(context.settings()).isSameAs(settings);
     assertThat(context.analysisMode()).isSameAs(analysisMode);
 
-    DefaultIssue defaultIssue = new DefaultIssue();
+    TrackedIssue defaultIssue = new TrackedIssue();
     defaultIssue.setComponentKey("foo:src/Foo.php");
     defaultIssue.setEffortToFix(2.0);
     defaultIssue.setNew(true);
     defaultIssue.setKey("xyz");
-    defaultIssue.setLine(1);
+    defaultIssue.setStartLine(1);
     defaultIssue.setMessage("msg");
     defaultIssue.setSeverity("BLOCKER");
     when(issueCache.all()).thenReturn(Arrays.asList(defaultIssue));
index fc3355952c02e2ea229406b12117878677a0ae66..998192b798561151d6cbf9eb2e7f274bf6fc1e51 100644 (file)
  */
 package org.sonar.batch.scan.report;
 
+import javax.annotation.Nullable;
+
+import org.sonar.batch.issue.tracking.TrackedIssue;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.config.Settings;
-import org.sonar.core.issue.DefaultIssue;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.batch.issue.IssueCache;
@@ -68,7 +70,7 @@ public class ConsoleReportTest {
   public void testNoFile() {
     settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
     when(inputPathCache.allFiles()).thenReturn(Collections.<InputFile>emptyList());
-    when(issueCache.all()).thenReturn(Collections.<DefaultIssue>emptyList());
+    when(issueCache.all()).thenReturn(Collections.<TrackedIssue>emptyList());
     report.execute();
     assertThat(getReportLog()).isEqualTo(
       "\n\n-------------  Issues Report  -------------\n\n" +
@@ -80,7 +82,7 @@ public class ConsoleReportTest {
   public void testNoNewIssue() {
     settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
     when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php")));
-    when(issueCache.all()).thenReturn(Arrays.asList(new DefaultIssue().setNew(false)));
+    when(issueCache.all()).thenReturn(Arrays.asList(createIssue(false, null)));
     report.execute();
     assertThat(getReportLog()).isEqualTo(
       "\n\n-------------  Issues Report  -------------\n\n" +
@@ -92,7 +94,7 @@ public class ConsoleReportTest {
   public void testOneNewIssue() {
     settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
     when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php")));
-    when(issueCache.all()).thenReturn(Arrays.asList(new DefaultIssue().setNew(true).setSeverity(Severity.BLOCKER)));
+    when(issueCache.all()).thenReturn(Arrays.asList(createIssue(true, Severity.BLOCKER)));
     report.execute();
     assertThat(getReportLog()).isEqualTo(
       "\n\n-------------  Issues Report  -------------\n\n" +
@@ -105,11 +107,12 @@ public class ConsoleReportTest {
   public void testOneNewIssuePerSeverity() {
     settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
     when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php")));
-    when(issueCache.all()).thenReturn(Arrays.asList(new DefaultIssue().setNew(true).setSeverity(Severity.BLOCKER),
-      new DefaultIssue().setNew(true).setSeverity(Severity.CRITICAL),
-      new DefaultIssue().setNew(true).setSeverity(Severity.MAJOR),
-      new DefaultIssue().setNew(true).setSeverity(Severity.MINOR),
-      new DefaultIssue().setNew(true).setSeverity(Severity.INFO)));
+    when(issueCache.all()).thenReturn(Arrays.asList(
+      createIssue(true, Severity.BLOCKER),
+      createIssue(true, Severity.CRITICAL),
+      createIssue(true, Severity.MAJOR),
+      createIssue(true, Severity.MINOR),
+      createIssue(true, Severity.INFO)));
     report.execute();
     assertThat(getReportLog()).isEqualTo(
       "\n\n-------------  Issues Report  -------------\n\n" +
@@ -131,4 +134,12 @@ public class ConsoleReportTest {
     throw new IllegalStateException("No console report");
   }
 
+  private TrackedIssue createIssue(boolean isNew, @Nullable String severity) {
+    TrackedIssue issue = new TrackedIssue();
+    issue.setNew(isNew);
+    issue.setSeverity(severity);
+
+    return issue;
+  }
+
 }
index 92f8207baac5214edfaab3aacc5606f2faf40d33..0cf45185cfee2398309b6b99cb654b8dd06bd6c7 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.batch.scan.report;
 
+import org.sonar.batch.issue.tracking.TrackedIssue;
+
 import com.google.common.collect.Lists;
 
 import java.io.File;
@@ -49,7 +51,6 @@ import org.sonar.batch.issue.IssueCache;
 import org.sonar.batch.protocol.input.BatchInput;
 import org.sonar.batch.repository.user.UserRepositoryLoader;
 import org.sonar.batch.scan.filesystem.InputPathCache;
-import org.sonar.core.issue.DefaultIssue;
 import org.sonar.test.JsonAssert;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -99,21 +100,23 @@ public class JSONReportTest {
 
   @Test
   public void should_write_json() throws Exception {
-    DefaultIssue issue = new DefaultIssue()
-      .setKey("200")
-      .setComponentKey("struts:src/main/java/org/apache/struts/Action.java")
-      .setRuleKey(RuleKey.of("squid", "AvoidCycles"))
-      .setMessage("There are 2 cycles")
-      .setSeverity("MINOR")
-      .setStatus(Issue.STATUS_OPEN)
-      .setResolution(null)
-      .setLine(1)
-      .setEffortToFix(3.14)
-      .setReporter("julien")
-      .setAssignee("simon")
-      .setCreationDate(SIMPLE_DATE_FORMAT.parse("2013-04-24"))
-      .setUpdateDate(SIMPLE_DATE_FORMAT.parse("2013-04-25"))
-      .setNew(false);
+    TrackedIssue issue = new TrackedIssue();
+    issue.setKey("200");
+    issue.setComponentKey("struts:src/main/java/org/apache/struts/Action.java");
+    issue.setRuleKey(RuleKey.of("squid", "AvoidCycles"));
+    issue.setMessage("There are 2 cycles");
+    issue.setSeverity("MINOR");
+    issue.setStatus(Issue.STATUS_OPEN);
+    issue.setResolution(null);
+    issue.setStartLine(1);
+    issue.setEndLine(2);
+    issue.setStartLineOffset(3);
+    issue.setEndLineOffset(4);
+    issue.setEffortToFix(3.14);
+    issue.setReporter("julien");
+    issue.setAssignee("simon");
+    issue.setCreationDate(SIMPLE_DATE_FORMAT.parse("2013-04-24"));
+    issue.setNew(false);
     when(issueCache.all()).thenReturn(Lists.newArrayList(issue));
     BatchInput.User user1 = BatchInput.User.newBuilder().setLogin("julien").setName("Julien").build();
     BatchInput.User user2 = BatchInput.User.newBuilder().setLogin("simon").setName("Simon").build();
@@ -129,16 +132,14 @@ public class JSONReportTest {
   @Test
   public void should_exclude_resolved_issues() throws Exception {
     RuleKey ruleKey = RuleKey.of("squid", "AvoidCycles");
-    DefaultIssue issue = new DefaultIssue()
-      .setKey("200")
-      .setComponentKey("struts:src/main/java/org/apache/struts/Action.java")
-      .setRuleKey(ruleKey)
-      .setStatus(Issue.STATUS_CLOSED)
-      .setResolution(Issue.RESOLUTION_FIXED)
-      .setCreationDate(SIMPLE_DATE_FORMAT.parse("2013-04-24"))
-      .setUpdateDate(SIMPLE_DATE_FORMAT.parse("2013-04-25"))
-      .setCloseDate(SIMPLE_DATE_FORMAT.parse("2013-04-26"))
-      .setNew(false);
+    TrackedIssue issue = new TrackedIssue();
+    issue.setKey("200");
+    issue.setComponentKey("struts:src/main/java/org/apache/struts/Action.java");
+    issue.setRuleKey(ruleKey);
+    issue.setStatus(Issue.STATUS_CLOSED);
+    issue.setResolution(Issue.RESOLUTION_FIXED);
+    issue.setCreationDate(SIMPLE_DATE_FORMAT.parse("2013-04-24"));
+    issue.setNew(false);
     when(issueCache.all()).thenReturn(Lists.newArrayList(issue));
 
     StringWriter writer = new StringWriter();
@@ -149,7 +150,7 @@ public class JSONReportTest {
 
   @Test
   public void should_ignore_components_without_issue() {
-    when(issueCache.all()).thenReturn(Collections.<DefaultIssue>emptyList());
+    when(issueCache.all()).thenReturn(Collections.<TrackedIssue>emptyList());
 
     StringWriter writer = new StringWriter();
     jsonReport.writeJson(writer);
@@ -172,7 +173,7 @@ public class JSONReportTest {
     File workDir = temp.newFolder("sonar");
     fs.setWorkDir(workDir);
 
-    when(issueCache.all()).thenReturn(Collections.<DefaultIssue>emptyList());
+    when(issueCache.all()).thenReturn(Collections.<TrackedIssue>emptyList());
 
     settings.setProperty("sonar.report.export.path", "output.json");
 
index 91c1e3a3eac4b84c4bc31dc7650f80ace94552d1..d05703e5d300eb4958271681c13f45f796a9da8f 100644 (file)
@@ -4,7 +4,10 @@
     {
       "key": "200",
       "component": "struts:src/main/java/org/apache/struts/Action.java",
-      "line": 1,
+      "startLine": 1,
+      "startOffset": 3,
+      "endLine": 2,
+      "endOffset": 4,
       "message": "There are 2 cycles",
       "severity": "MINOR",
       "rule": "squid:AvoidCycles",
index a7d0edb1803878b4a2d9b88e67654d544ff6a367..41cd417cff01ee51f7524d204adf945f7396f4dc 100644 (file)
@@ -32,7 +32,6 @@ import java.util.Set;
 import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateUtils;
-import org.sonar.api.batch.BatchSide;
 import org.sonar.api.issue.ActionPlan;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.server.rule.RuleTagFormat;
@@ -42,7 +41,6 @@ import org.sonar.api.utils.Duration;
 /**
  * Updates issue fields and chooses if changes must be kept in history.
  */
-@BatchSide
 @ServerSide
 public class IssueUpdater {
 
index cbd2c0661e0baec0ddef526db0ff128c45a8bd62..fa66bd4a976f78500825985ca045f381072d2047 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.core.issue.workflow;
 
 import java.util.List;
 import org.picocontainer.Startable;
-import org.sonar.api.batch.BatchSide;
 import org.sonar.api.issue.DefaultTransitions;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.issue.condition.HasResolution;
@@ -32,7 +31,6 @@ import org.sonar.core.issue.DefaultIssue;
 import org.sonar.core.issue.IssueChangeContext;
 import org.sonar.core.issue.IssueUpdater;
 
-@BatchSide
 @ServerSide
 public class IssueWorkflow implements Startable {