]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3346 Consume violations directly from PMD - no need to parse XML
authorEvgeny Mandrikov <mandrikov@gmail.com>
Mon, 26 Mar 2012 05:48:13 +0000 (11:48 +0600)
committerEvgeny Mandrikov <mandrikov@gmail.com>
Mon, 26 Mar 2012 11:57:47 +0000 (17:57 +0600)
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdExecutor.java
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdSensor.java
plugins/sonar-pmd-plugin/src/main/java/org/sonar/plugins/pmd/PmdViolationsXmlParser.java
plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/PmdExecutorTest.java

index 7c7e5e38bdbbf7ad2beca8b91adb044279b391b7..9b5eb9862bdc403b7f82d1413f831937ac57685c 100644 (file)
@@ -49,7 +49,7 @@ public class PmdExecutor implements BatchExtension {
     this.configuration = configuration;
   }
 
-  public File execute() throws IOException, PMDException {
+  public Report execute() throws IOException, PMDException {
     TimeProfiler profiler = new TimeProfiler().start("Execute PMD " + PmdVersion.getVersion());
 
     ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader();
@@ -80,7 +80,9 @@ public class PmdExecutor implements BatchExtension {
         }
       }
 
-      return writeXmlReport(project, report);
+      writeXmlReport(project, report);
+
+      return report;
 
     } finally {
       profiler.stop();
index d71283507bd33b09a4348d359999da5f05629ed7..c129ec1dfdafa2a234014ce8935a86aa978527e4 100644 (file)
  */
 package org.sonar.plugins.pmd;
 
+import net.sourceforge.pmd.IRuleViolation;
+import net.sourceforge.pmd.Report;
+import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.Sensor;
 import org.sonar.api.batch.SensorContext;
 import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.resources.JavaFile;
 import org.sonar.api.resources.Project;
+import org.sonar.api.resources.Resource;
+import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RuleFinder;
+import org.sonar.api.rules.Violation;
 import org.sonar.api.utils.XmlParserException;
 
-import java.io.File;
+import java.util.Iterator;
 
 public class PmdSensor implements Sensor {
 
@@ -42,8 +49,8 @@ public class PmdSensor implements Sensor {
 
   public void analyse(Project project, SensorContext context) {
     try {
-      File xmlReport = executor.execute();
-      getStaxParser(project, context).parse(xmlReport);
+      Report report = executor.execute();
+      analyseReport(report, project, context);
 
     } catch (Exception e) {
       // TOFIX
@@ -51,15 +58,32 @@ public class PmdSensor implements Sensor {
     }
   }
 
+  private void analyseReport(Report report, Project project, SensorContext context) {
+    Iterator<IRuleViolation> pmdViolationIter = report.iterator();
+    while (pmdViolationIter.hasNext()) {
+      IRuleViolation pmdViolation = pmdViolationIter.next();
+      int lineId = pmdViolation.getBeginLine();
+      String ruleKey = pmdViolation.getRule().getName();
+      String message = pmdViolation.getDescription();
+      String filename = pmdViolation.getFilename();
+      Resource resource = JavaFile.fromAbsolutePath(filename, project.getFileSystem().getSourceDirs(), false);
+      // Save violations only for existing resources
+      if (context.getResource(resource) != null) {
+        Rule rule = rulesFinder.findByKey(CoreProperties.PMD_PLUGIN, ruleKey);
+        // Save violations only for enabled rules
+        if (rule != null) {
+          Violation violation = Violation.create(rule, resource).setLineId(lineId).setMessage(message);
+          context.saveViolation(violation);
+        }
+      }
+    }
+  }
+
   public boolean shouldExecuteOnProject(Project project) {
     return project.getFileSystem().hasJavaSourceFiles() &&
         !profile.getActiveRulesByRepository(PmdConstants.REPOSITORY_KEY).isEmpty();
   }
 
-  private PmdViolationsXmlParser getStaxParser(Project project, SensorContext context) {
-    return new PmdViolationsXmlParser(project, rulesFinder, context);
-  }
-
   @Override
   public String toString() {
     return getClass().getSimpleName();
index 794bbf0c3069056c786dad731c9d726022f282c2..f38b8cb8ba38f3cd8962b523f3c9945d077ceaa7 100644 (file)
@@ -33,8 +33,10 @@ import org.sonar.api.rules.Violation;
 import org.sonar.api.utils.StaxParser;
 
 import javax.xml.stream.XMLStreamException;
+
 import java.io.File;
 
+@Deprecated
 class PmdViolationsXmlParser {
 
   private Project project;
index a5597bb68727c57c53c0fb06d994145108eaaa50..4ed43df39511e4bd0b85c917da5c19202bff862b 100644 (file)
@@ -22,7 +22,9 @@ package org.sonar.plugins.pmd;
 import net.sourceforge.pmd.PMDException;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.sonar.api.resources.Java;
 import org.sonar.api.resources.Project;
 import org.sonar.api.resources.ProjectFileSystem;
@@ -42,15 +44,19 @@ import static org.mockito.Mockito.when;
 
 public class PmdExecutorTest {
 
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
   @Test
   public void executeOnManySourceDirs() throws URISyntaxException, IOException, PMDException {
+    final File workDir = temp.getRoot();
     Project project = new Project("two-source-dirs");
 
     ProjectFileSystem fs = mock(ProjectFileSystem.class);
     File root = new File(getClass().getResource("/org/sonar/plugins/pmd/PmdExecutorTest/executeOnManySourceDirs/").toURI());
     when(fs.getSourceFiles(Java.INSTANCE)).thenReturn(Arrays.asList(new File(root, "src1/FirstClass.java"), new File(root, "src2/SecondClass.java")));
     when(fs.getSourceCharset()).thenReturn(Charset.forName("UTF-8"));
-    when(fs.getSonarWorkingDirectory()).thenReturn(new File("target"));
+    when(fs.getSonarWorkingDirectory()).thenReturn(workDir);
     project.setFileSystem(fs);
 
     PmdConfiguration conf = mock(PmdConfiguration.class);
@@ -58,7 +64,8 @@ public class PmdExecutorTest {
     when(conf.getRulesets()).thenReturn(Arrays.asList(file.getAbsolutePath()));
 
     PmdExecutor executor = new PmdExecutor(project, conf);
-    File xmlReport = executor.execute();
+    executor.execute();
+    File xmlReport = new File(workDir, "pmd-result.xml");
     assertThat(xmlReport.exists(), is(true));
 
     String xml = FileUtils.readFileToString(xmlReport);
@@ -70,19 +77,21 @@ public class PmdExecutorTest {
 
   @Test
   public void ignorePmdFailures() throws URISyntaxException, IOException, PMDException {
+    final File workDir = temp.getRoot();
     Project project = new Project("ignorePmdFailures");
 
     ProjectFileSystem fs = mock(ProjectFileSystem.class);
     when(fs.getSourceFiles(Java.INSTANCE)).thenReturn(Arrays.asList(new File("test-resources/ignorePmdFailures/DoesNotCompile.java")));
     when(fs.getSourceCharset()).thenReturn(Charset.forName("UTF-8"));
-    when(fs.getSonarWorkingDirectory()).thenReturn(new File("target"));
+    when(fs.getSonarWorkingDirectory()).thenReturn(workDir);
     project.setFileSystem(fs);
 
     PmdConfiguration conf = mock(PmdConfiguration.class);
     when(conf.getRulesets()).thenReturn(Arrays.asList(new File("test-resources/ignorePmdFailures/pmd.xml").getAbsolutePath()));
 
     PmdExecutor executor = new PmdExecutor(project, conf);
-    File xmlReport = executor.execute();
+    executor.execute();
+    File xmlReport = new File(workDir, "pmd-result.xml");
     assertThat(xmlReport.exists(), is(true));
   }