]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3347 Limit time of analysis of single file for bridge between PMD and Sonar CPD
authorEvgeny Mandrikov <mandrikov@gmail.com>
Mon, 26 Mar 2012 06:18:44 +0000 (12:18 +0600)
committerEvgeny Mandrikov <mandrikov@gmail.com>
Mon, 26 Mar 2012 06:54:14 +0000 (12:54 +0600)
plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarBridgeEngine.java
plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/SonarEngine.java

index 7aee8b8ed4ae9ed0415d6acf06ef4128a9b58216..026893d031cc363f9280b42bfc9ec36451c2a59e 100644 (file)
@@ -22,12 +22,14 @@ package org.sonar.plugins.cpd;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.sonar.api.batch.CpdMapping;
 import org.sonar.api.batch.SensorContext;
 import org.sonar.api.resources.*;
+import org.sonar.api.utils.SonarException;
 import org.sonar.duplications.DuplicationPredicates;
 import org.sonar.duplications.block.Block;
-import org.sonar.duplications.detector.suffixtree.SuffixTreeCloneDetectionAlgorithm;
 import org.sonar.duplications.index.CloneGroup;
 import org.sonar.duplications.internal.pmd.TokenizerBridge;
 import org.sonar.plugins.cpd.index.IndexFactory;
@@ -35,9 +37,17 @@ import org.sonar.plugins.cpd.index.SonarDuplicationsIndex;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.*;
 
 public class SonarBridgeEngine extends CpdEngine {
 
+  private static final Logger LOG = LoggerFactory.getLogger(SonarBridgeEngine.class);
+
+  /**
+   * Limit of time to analyse one file (in seconds).
+   */
+  private static final int TIMEOUT = 5 * 60;
+
   private final IndexFactory indexFactory;
   private final CpdMapping[] mappings;
 
@@ -71,6 +81,7 @@ public class SonarBridgeEngine extends CpdEngine {
 
     TokenizerBridge bridge = new TokenizerBridge(mapping.getTokenizer(), fileSystem.getSourceCharset().name(), getBlockSize(project));
     for (InputFile inputFile : inputFiles) {
+      LOG.debug("Populating index from {}", inputFile.getFile());
       Resource resource = mapping.createResource(inputFile.getFile(), fileSystem.getSourceDirs());
       String resourceId = SonarEngine.getFullKey(project, resource);
       List<Block> blocks = bridge.chunk(resourceId, inputFile.getFile());
@@ -80,16 +91,32 @@ public class SonarBridgeEngine extends CpdEngine {
     // Detect
     Predicate<CloneGroup> minimumTokensPredicate = DuplicationPredicates.numberOfUnitsNotLessThan(PmdEngine.getMinimumTokens(project));
 
-    for (InputFile inputFile : inputFiles) {
-      Resource resource = mapping.createResource(inputFile.getFile(), fileSystem.getSourceDirs());
-      String resourceKey = SonarEngine.getFullKey(project, resource);
-
-      Collection<Block> fileBlocks = index.getByResource(resource, resourceKey);
-      List<CloneGroup> duplications = SuffixTreeCloneDetectionAlgorithm.detect(index, fileBlocks);
-
-      Iterable<CloneGroup> filtered = Iterables.filter(duplications, minimumTokensPredicate);
+    ExecutorService executorService = Executors.newSingleThreadExecutor();
+    try {
+      for (InputFile inputFile : inputFiles) {
+        LOG.debug("Detection of duplications for {}", inputFile.getFile());
+        Resource resource = mapping.createResource(inputFile.getFile(), fileSystem.getSourceDirs());
+        String resourceKey = SonarEngine.getFullKey(project, resource);
+
+        Collection<Block> fileBlocks = index.getByResource(resource, resourceKey);
+
+        Iterable<CloneGroup> filtered;
+        try {
+          List<CloneGroup> duplications = executorService.submit(new SonarEngine.Task(index, fileBlocks)).get(TIMEOUT, TimeUnit.SECONDS);
+          filtered = Iterables.filter(duplications, minimumTokensPredicate);
+        } catch (TimeoutException e) {
+          filtered = null;
+          LOG.warn("Timeout during detection of duplications for " + inputFile.getFile(), e);
+        } catch (InterruptedException e) {
+          throw new SonarException(e);
+        } catch (ExecutionException e) {
+          throw new SonarException(e);
+        }
 
-      SonarEngine.save(context, resource, filtered);
+        SonarEngine.save(context, resource, filtered);
+      }
+    } finally {
+      executorService.shutdown();
     }
   }
 
index 460fdd10fa0988ce00252d3efaee40704705a2e8..88c2c90656ae23c21d44a91f7976760018b022ed 100644 (file)
@@ -156,7 +156,7 @@ public class SonarEngine extends CpdEngine {
     }
   }
 
-  private static class Task implements Callable<List<CloneGroup>> {
+  static class Task implements Callable<List<CloneGroup>> {
     private final CloneIndex index;
     private final Collection<Block> fileBlocks;