]> source.dussan.org Git - sonarqube.git/commitdiff
Fix quality flaws
authorJulien HENRY <henryju@yahoo.fr>
Thu, 15 Dec 2016 15:31:58 +0000 (16:31 +0100)
committerJulien HENRY <henryju@yahoo.fr>
Fri, 16 Dec 2016 08:49:58 +0000 (09:49 +0100)
31 files changed:
server/sonar-server/src/main/java/org/sonar/server/issue/SetSeverityAction.java
server/sonar-server/src/main/java/org/sonar/server/notification/DefaultNotificationManager.java
sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbstractFilePredicate.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultFileSystem.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/internal/DefaultHighlighting.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/DefaultFileLinesContext.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdExecutor.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/index/SonarCpdBlockIndex.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/index/DefaultIndex.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/FileHashes.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/InitializerExecutionEvent.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/InitializersPhaseEvent.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PostJobExecutionEvent.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/PostJobPhaseEvent.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/ProjectAnalysisEvent.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorExecutionEvent.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/profiling/AbstractTimeProfiling.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ActiveRulesPublisher.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MeasuresPublisher.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/TestExecutionAndCoveragePublisher.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/DefaultProjectRepositoriesLoader.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/rule/DefaultActiveRulesLoader.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/measure/DeprecatedMetricFinder.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultHighlightable.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java

index 8a521e5f0970e1b474cd1cbe3b1c610f8d8c0f3f..5bb3c9fc8a6d1635b2ade25d6edc377dead3b02f 100644 (file)
@@ -23,7 +23,6 @@ import com.google.common.base.Strings;
 import java.util.Collection;
 import java.util.Map;
 import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.condition.Condition;
 import org.sonar.api.issue.condition.IsUnResolved;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.web.UserRole;
@@ -42,12 +41,7 @@ public class SetSeverityAction extends Action {
     super(SET_SEVERITY_KEY);
     this.issueUpdater = issueUpdater;
     this.userSession = userSession;
-    super.setConditions(new IsUnResolved(), new Condition() {
-      @Override
-      public boolean matches(Issue issue) {
-        return isCurrentUserIssueAdmin(issue.projectKey());
-      }
-    });
+    super.setConditions(new IsUnResolved(), issue -> isCurrentUserIssueAdmin(issue.projectKey()));
   }
 
   private boolean isCurrentUserIssueAdmin(String projectKey) {
index bceb9aa8c4a114cb5cdbe0e4b6f66324108423ad..83548fbd63143ee8158a62904499a256d88632b1 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.server.notification;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Multimap;
@@ -78,12 +77,7 @@ public class DefaultNotificationManager implements NotificationManager {
 
   @Override
   public void scheduleForSending(List<Notification> notification) {
-    notificationQueueDao.insert(Lists.transform(notification, new Function<Notification, NotificationQueueDto>() {
-      @Override
-      public NotificationQueueDto apply(Notification notification) {
-        return NotificationQueueDto.toNotificationQueueDto(notification);
-      }
-    }));
+    notificationQueueDao.insert(Lists.transform(notification, NotificationQueueDto::toNotificationQueueDto));
   }
 
   /**
@@ -130,7 +124,7 @@ public class DefaultNotificationManager implements NotificationManager {
    */
   @Override
   public Multimap<String, NotificationChannel> findSubscribedRecipientsForDispatcher(NotificationDispatcher dispatcher,
-                                                                                     @Nullable String projectUuid) {
+    @Nullable String projectUuid) {
     String dispatcherKey = dispatcher.getKey();
 
     SetMultimap<String, NotificationChannel> recipients = HashMultimap.create();
index 12b5f9ae573c6945153efb3394c9e5f9a3a1efb3..7202e1af7ce2c0d8b621a01df1369fb655a62bcd 100644 (file)
@@ -26,8 +26,9 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
 import java.io.Serializable;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
@@ -41,7 +42,6 @@ import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.builder.ToStringBuilder;
 import org.apache.commons.lang.builder.ToStringStyle;
-import org.apache.commons.lang.time.DateUtils;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.issue.IssueComment;
 import org.sonar.api.rule.RuleKey;
@@ -306,7 +306,6 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
     return effort;
   }
 
-
   @CheckForNull
   public Long effortInMinutes() {
     return effort != null ? effort.toMinutes() : null;
@@ -366,11 +365,20 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
   }
 
   public DefaultIssue setCreationDate(Date d) {
-    // d is not marked as Nullable but we still allow null parameter for unit testing.
-    this.creationDate = d != null ? DateUtils.truncate(d, Calendar.SECOND) : null;
+    this.creationDate = truncateToSeconds(d);
     return this;
   }
 
+  @CheckForNull
+  private static Date truncateToSeconds(@Nullable Date d) {
+    if (d == null) {
+      return null;
+    }
+    Instant instant = d.toInstant();
+    instant = instant.truncatedTo(ChronoUnit.SECONDS);
+    return Date.from(instant);
+  }
+
   @Override
   @CheckForNull
   public Date updateDate() {
@@ -378,7 +386,7 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
   }
 
   public DefaultIssue setUpdateDate(@Nullable Date d) {
-    this.updateDate = d != null ? DateUtils.truncate(d, Calendar.SECOND) : null;
+    this.updateDate = truncateToSeconds(d);
     return this;
   }
 
@@ -389,7 +397,7 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
   }
 
   public DefaultIssue setCloseDate(@Nullable Date d) {
-    this.closeDate = d != null ? DateUtils.truncate(d, Calendar.SECOND) : null;
+    this.closeDate = truncateToSeconds(d);
     return this;
   }
 
@@ -580,7 +588,7 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure.
 
   @CheckForNull
   public <T> T getLocations() {
-    return (T)locations;
+    return (T) locations;
   }
 
   public DefaultIssue setLocations(@Nullable Object locations) {
index 98533a05154384d858b7a81e1c58ad81c54ecde1..2aff265bcf1b3ccd0dfac35d11e7f81ccc4ca118 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.api.batch.fs.internal;
 
-import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import org.sonar.api.batch.fs.FilePredicate;
 import org.sonar.api.batch.fs.FileSystem.Index;
@@ -36,12 +35,7 @@ public abstract class AbstractFilePredicate implements OptimizedFilePredicate {
 
   @Override
   public Iterable<InputFile> filter(Iterable<InputFile> target) {
-    return Iterables.filter(target, new Predicate<InputFile>() {
-      @Override
-      public boolean apply(InputFile input) {
-        return AbstractFilePredicate.this.apply(input);
-      }
-    });
+    return Iterables.filter(target, this::apply);
   }
 
   @Override
index ceeadaad22b04254bff11d1dddde1187685195c1..c7339ed1b2be833196d9d8317af27433435afb36 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.api.batch.fs.internal;
 
-import com.google.common.base.Function;
 import com.google.common.collect.Iterables;
 import java.io.File;
 import java.io.IOException;
@@ -33,7 +32,6 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
-import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.api.batch.fs.FilePredicate;
 import org.sonar.api.batch.fs.FilePredicates;
@@ -172,12 +170,7 @@ public class DefaultFileSystem implements FileSystem {
   @Override
   public Iterable<File> files(FilePredicate predicate) {
     doPreloadFiles();
-    return Iterables.transform(inputFiles(predicate), new Function<InputFile, File>() {
-      @Override
-      public File apply(InputFile input) {
-        return input.file();
-      }
-    });
+    return Iterables.transform(inputFiles(predicate), InputFile::file);
   }
 
   @Override
@@ -249,16 +242,6 @@ public class DefaultFileSystem implements FileSystem {
   }
 
   public abstract static class Cache implements Index {
-    @Override
-    public abstract Iterable<InputFile> inputFiles();
-
-    @Override
-    @CheckForNull
-    public abstract InputFile inputFile(String relativePath);
-
-    @Override
-    @CheckForNull
-    public abstract InputDir inputDir(String relativePath);
 
     protected abstract void doAdd(InputFile inputFile);
 
index c72d3e1a74450dfb6b3d7089c63e401e90acbf11..9a196396462fc23c600cb497ae8bd33c5d725f4a 100644 (file)
@@ -367,6 +367,7 @@ public class FileMetadata {
     }
   }
 
+  @FunctionalInterface
   public interface LineHashConsumer {
 
     void consume(int lineIdx, @Nullable byte[] hash);
index 6ccc541dad3bb9e621c113942007a4e3bd6d46df..add43c51cfde0133f2dcef2a8dedf02c380dd076 100644 (file)
@@ -22,7 +22,6 @@ package org.sonar.api.batch.sensor.highlighting.internal;
 import com.google.common.base.Preconditions;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import org.sonar.api.batch.fs.InputFile;
@@ -109,15 +108,12 @@ public class DefaultHighlighting extends DefaultStorable implements NewHighlight
   protected void doSave() {
     checkInputFileNotNull();
     // Sort rules to avoid variation during consecutive runs
-    Collections.sort(syntaxHighlightingRules, new Comparator<SyntaxHighlightingRule>() {
-      @Override
-      public int compare(SyntaxHighlightingRule left, SyntaxHighlightingRule right) {
-        int result = left.range().start().compareTo(right.range().start());
-        if (result == 0) {
-          result = right.range().end().compareTo(left.range().end());
-        }
-        return result;
+    Collections.sort(syntaxHighlightingRules, (left, right) -> {
+      int result = left.range().start().compareTo(right.range().start());
+      if (result == 0) {
+        result = right.range().end().compareTo(left.range().end());
       }
+      return result;
     });
     checkOverlappingBoudaries();
     storage.store(this);
index ec123e4df969b655f87d58ce66c4f55ff3ce09d6..ef9db3061bb5e97b1d1bb1045d66e3be146b531d 100644 (file)
  */
 package org.sonar.api.batch.sensor.issue.internal;
 
-import com.google.common.base.Function;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -37,21 +35,10 @@ import org.sonar.api.batch.sensor.issue.NewIssueLocation;
 import org.sonar.api.rule.RuleKey;
 
 import static java.lang.String.format;
+import static java.util.stream.Collectors.toList;
 
 public class DefaultIssue extends DefaultStorable implements Issue, NewIssue {
 
-  private static final class ToFlow implements Function<List<IssueLocation>, Flow> {
-    @Override
-    public Flow apply(final List<IssueLocation> input) {
-      return new Flow() {
-        @Override
-        public List<IssueLocation> locations() {
-          return ImmutableList.copyOf(input);
-        }
-      };
-    }
-  }
-
   private RuleKey ruleKey;
   private Double gap;
   private Severity overriddenSeverity;
@@ -147,7 +134,9 @@ public class DefaultIssue extends DefaultStorable implements Issue, NewIssue {
 
   @Override
   public List<Flow> flows() {
-    return Lists.transform(this.flows, new ToFlow());
+    return this.flows.stream()
+      .<Flow>map(l -> () -> ImmutableList.copyOf(l))
+      .collect(toList());
   }
 
   @Override
index ba4aa897646a163b8a2a75bf915e660970c65e5a..ad4f0770f3b4f8976688c748d7b0f450a47360b9 100644 (file)
@@ -21,7 +21,6 @@ package org.sonar.api.batch.sensor.symbol.internal;
 
 import com.google.common.base.Preconditions;
 import java.util.Collection;
-import java.util.Comparator;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
@@ -86,12 +85,7 @@ public class DefaultSymbolTable extends DefaultStorable implements NewSymbolTabl
   @Override
   public NewSymbol newSymbol(TextRange range) {
     checkInputFileNotNull();
-    TreeSet<TextRange> references = new TreeSet<>(new Comparator<TextRange>() {
-      @Override
-      public int compare(TextRange o1, TextRange o2) {
-        return o1.start().compareTo(o2.start());
-      }
-    });
+    TreeSet<TextRange> references = new TreeSet<>((o1, o2) -> o1.start().compareTo(o2.start()));
     referencesBySymbol.put(range, references);
     return new DefaultSymbol(inputFile, range, references);
   }
index 2a22d573b1e7d65ef3ddf3b938c5c68915213c42..03cfe4ba8dab3ea229d4da51178179a46a6f4c32 100644 (file)
@@ -21,10 +21,10 @@ package org.sonar.scanner;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 import java.util.Map;
+import java.util.Map.Entry;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.sensor.SensorContext;
@@ -35,17 +35,10 @@ import org.sonar.api.utils.KeyValueFormat;
 import org.sonar.api.utils.KeyValueFormat.Converter;
 import org.sonar.scanner.scan.measure.MeasureCache;
 
-import static com.google.common.collect.Maps.filterValues;
+import static java.util.stream.Collectors.toMap;
 
 public class DefaultFileLinesContext implements FileLinesContext {
 
-  private static final Predicate<Object> LINES_WITH_NON_ZERO_VALUE = new Predicate<Object>() {
-    @Override
-    public boolean apply(Object input) {
-      return !input.equals(0);
-    }
-  };
-
   private final SensorContext context;
   private final InputFile inputFile;
   private final MetricFinder metricFinder;
@@ -146,7 +139,9 @@ public class DefaultFileLinesContext implements FileLinesContext {
   private static Map optimizeStorage(String metricKey, Map<Integer, Object> lines) {
     // SONAR-7464 Don't store 0 because this is default value anyway
     if (CoreMetrics.NCLOC_DATA_KEY.equals(metricKey) || CoreMetrics.COMMENT_LINES_DATA_KEY.equals(metricKey) || CoreMetrics.EXECUTABLE_LINES_DATA_KEY.equals(metricKey)) {
-      return filterValues(lines, LINES_WITH_NON_ZERO_VALUE);
+      return lines.entrySet().stream()
+        .filter(entry -> !entry.getValue().equals(0))
+        .collect(toMap(Entry<Integer, Object>::getKey, Entry<Integer, Object>::getValue));
     }
     return lines;
   }
index c3ca55c4507b1b9581815c758f34248a49abb2e1..db8ba5417cb68b8747637ee974a493cbe024f980 100644 (file)
@@ -58,7 +58,7 @@ import static com.google.common.collect.FluentIterable.from;
 public class CpdExecutor {
   private static final Logger LOG = Loggers.get(CpdExecutor.class);
   // timeout for the computation of duplicates in a file (seconds)
-  private static final int TIMEOUT = 5 * 60;
+  private static final int TIMEOUT = 5 * 60 * 1000;
   static final int MAX_CLONE_GROUP_PER_FILE = 100;
   static final int MAX_CLONE_PART_PER_GROUP = 100;
 
@@ -66,7 +66,6 @@ public class CpdExecutor {
   private final ReportPublisher publisher;
   private final BatchComponentCache batchComponentCache;
   private final Settings settings;
-  private final ExecutorService executorService;
   private final ProgressReport progressReport;
   private int count;
   private int total;
@@ -76,50 +75,54 @@ public class CpdExecutor {
     this.index = index;
     this.publisher = publisher;
     this.batchComponentCache = batchComponentCache;
-    this.executorService = Executors.newSingleThreadExecutor();
     this.progressReport = new ProgressReport("CPD computation", TimeUnit.SECONDS.toMillis(10));
   }
 
   public void execute() {
+    execute(TIMEOUT);
+  }
+
+  @VisibleForTesting
+  void execute(long timeout) {
     total = index.noResources();
     progressReport.start(String.format("Calculating CPD for %d files", total));
+    ExecutorService executorService = Executors.newSingleThreadExecutor();
     try {
       Iterator<ResourceBlocks> it = index.iterator();
 
       while (it.hasNext()) {
         ResourceBlocks resourceBlocks = it.next();
-        runCpdAnalysis(resourceBlocks.resourceId(), resourceBlocks.blocks());
+        runCpdAnalysis(executorService, resourceBlocks.resourceId(), resourceBlocks.blocks(), timeout);
         count++;
       }
       progressReport.stop("CPD calculation finished");
     } catch (Exception e) {
       progressReport.stop("");
       throw e;
+    } finally {
+      executorService.shutdown();
     }
   }
 
-  private void runCpdAnalysis(String resource, final Collection<Block> fileBlocks) {
-    LOG.debug("Detection of duplications for {}", resource);
-
-    BatchComponent component = batchComponentCache.get(resource);
+  @VisibleForTesting
+  void runCpdAnalysis(ExecutorService executorService, String componentKey, final Collection<Block> fileBlocks, long timeout) {
+    BatchComponent component = batchComponentCache.get(componentKey);
     if (component == null) {
-      LOG.error("Resource not found in component cache: {}. Skipping CPD computation for it", resource);
+      LOG.error("Resource not found in component cache: {}. Skipping CPD computation for it", componentKey);
       return;
     }
 
     InputFile inputFile = (InputFile) component.inputComponent();
+    LOG.debug("Detection of duplications for {}", inputFile.absolutePath());
     progressReport.message(String.format("%d/%d - current file: %s", count, total, inputFile.absolutePath()));
 
     List<CloneGroup> duplications;
-    Future<List<CloneGroup>> futureResult = null;
+    Future<List<CloneGroup>> futureResult = executorService.submit(() -> SuffixTreeCloneDetectionAlgorithm.detect(index, fileBlocks));
     try {
-      futureResult = executorService.submit(() -> SuffixTreeCloneDetectionAlgorithm.detect(index, fileBlocks));
-      duplications = futureResult.get(TIMEOUT, TimeUnit.SECONDS);
+      duplications = futureResult.get(timeout, TimeUnit.MILLISECONDS);
     } catch (TimeoutException e) {
       LOG.warn("Timeout during detection of duplications for " + inputFile.absolutePath());
-      if (futureResult != null) {
-        futureResult.cancel(true);
-      }
+      futureResult.cancel(true);
       return;
     } catch (Exception e) {
       throw new IllegalStateException("Fail during detection of duplication for " + inputFile.absolutePath(), e);
@@ -158,7 +161,7 @@ public class CpdExecutor {
       LOG.warn("Too many duplication groups on file " + component.inputComponent() + ". Keep only the first " + MAX_CLONE_GROUP_PER_FILE +
         " groups.");
     }
-    Iterable<org.sonar.scanner.protocol.output.ScannerReport.Duplication> reportDuplications = from(duplications)
+    Iterable<ScannerReport.Duplication> reportDuplications = from(duplications)
       .limit(MAX_CLONE_GROUP_PER_FILE)
       .transform(
         new Function<CloneGroup, ScannerReport.Duplication>() {
index b20e5f2c76382bd85822a406ac379bf49c4ccf49..619a06e4c20bb42c610d9db37e39f16b6d307119 100644 (file)
  */
 package org.sonar.scanner.cpd.index;
 
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
+import java.util.stream.Collectors;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.fs.InputFile;
@@ -62,18 +61,15 @@ public class SonarCpdBlockIndex extends AbstractCloneIndex {
         throw new UnsupportedOperationException("Trying to save CPD tokens twice for the same file is not supported: " + inputFile.absolutePath());
       }
       final ScannerReport.CpdTextBlock.Builder builder = ScannerReport.CpdTextBlock.newBuilder();
-      publisher.getWriter().writeCpdTextBlocks(id, Iterables.transform(blocks, new Function<Block, ScannerReport.CpdTextBlock>() {
-        @Override
-        public ScannerReport.CpdTextBlock apply(Block input) {
-          builder.clear();
-          builder.setStartLine(input.getStartLine());
-          builder.setEndLine(input.getEndLine());
-          builder.setStartTokenIndex(input.getStartUnit());
-          builder.setEndTokenIndex(input.getEndUnit());
-          builder.setHash(input.getBlockHash().toHexString());
-          return builder.build();
-        }
-      }));
+      publisher.getWriter().writeCpdTextBlocks(id, blocks.stream().map(block -> {
+        builder.clear();
+        builder.setStartLine(block.getStartLine());
+        builder.setEndLine(block.getEndLine());
+        builder.setStartTokenIndex(block.getStartUnit());
+        builder.setEndTokenIndex(block.getEndUnit());
+        builder.setHash(block.getBlockHash().toHexString());
+        return builder.build();
+      }).collect(Collectors.toList()));
     }
     for (Block block : blocks) {
       mem.insert(block);
index 851df66496250cb9aa803e5471b421e283388625..030518b26f5802ecc92bc36a8a296d7ac2aee126 100644 (file)
@@ -166,7 +166,7 @@ public class DefaultIndex {
   }
 
   private static Measure toDeprecated(org.sonar.api.batch.sensor.measure.Measure<?> measure) {
-    org.sonar.api.measures.Measure deprecatedMeasure = new org.sonar.api.measures.Measure((Metric<?>) measure.metric());
+    Measure deprecatedMeasure = new Measure((Metric<?>) measure.metric());
     setValueAccordingToMetricType(measure, deprecatedMeasure);
     return deprecatedMeasure;
   }
index c65081e5f4430318457e0f31f002828fdda3d3a9..bac3c9b688864e02b60c9836b8fce45ce8925367 100644 (file)
  */
 package org.sonar.scanner.issue.tracking;
 
-import org.sonar.api.batch.fs.internal.FileMetadata;
-import org.sonar.api.batch.fs.internal.FileMetadata.LineHashConsumer;
-
 import com.google.common.collect.LinkedHashMultimap;
 import com.google.common.collect.Multimap;
+import java.util.Collection;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.lang.ObjectUtils;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
-
-import javax.annotation.Nullable;
-
-import java.util.Collection;
+import org.sonar.api.batch.fs.internal.FileMetadata;
 
 /**
  * Wraps a {@link Sequence} to assign hash codes to elements.
@@ -57,13 +52,8 @@ public final class FileHashes {
 
   public static FileHashes create(DefaultInputFile f) {
     final byte[][] hashes = new byte[f.lines()][];
-    FileMetadata.computeLineHashesForIssueTracking(f, new LineHashConsumer() {
-
-      @Override
-      public void consume(int lineIdx, @Nullable byte[] hash) {
-        hashes[lineIdx - 1] = hash;
-      }
-    });
+    FileMetadata.computeLineHashesForIssueTracking(f,
+      (lineIdx, hash) -> hashes[lineIdx - 1] = hash);
 
     int size = hashes.length;
     Multimap<String, Integer> linesByHash = LinkedHashMultimap.create();
@@ -84,7 +74,7 @@ public final class FileHashes {
   public Collection<Integer> getLinesForHash(String hash) {
     return linesByHash.get(hash);
   }
-  
+
   public String[] hashes() {
     return hashes;
   }
index 1f7b4bbd0671a896a121017e5064809c504af64f..1ce95e83387c42604e99cde27f95c414cdafe1d3 100644 (file)
@@ -23,7 +23,7 @@ import org.sonar.api.batch.Initializer;
 import org.sonar.api.batch.events.InitializerExecutionHandler;
 
 class InitializerExecutionEvent extends AbstractPhaseEvent<InitializerExecutionHandler>
-    implements org.sonar.api.batch.events.InitializerExecutionHandler.InitializerExecutionEvent {
+  implements InitializerExecutionHandler.InitializerExecutionEvent {
 
   private final Initializer initializer;
 
index 6a45a4d67e599808049e8fde00e3ed2c7e1d3510..fa54af9f9b06e6bccb59bb5b099a2c5c76303134 100644 (file)
  */
 package org.sonar.scanner.phases;
 
+import java.util.List;
 import org.sonar.api.batch.Initializer;
 import org.sonar.api.batch.events.InitializersPhaseHandler;
 
-import java.util.List;
-
 class InitializersPhaseEvent extends AbstractPhaseEvent<InitializersPhaseHandler>
-    implements org.sonar.api.batch.events.InitializersPhaseHandler.InitializersPhaseEvent {
+  implements InitializersPhaseHandler.InitializersPhaseEvent {
 
   private final List<Initializer> initializers;
 
index 3c519326f06d63d2ac0cc70fd95b3948ec4e423d..b49abcb2df78b261a9b22a7889db2d9428add7b7 100644 (file)
@@ -23,7 +23,7 @@ import org.sonar.api.batch.PostJob;
 import org.sonar.api.batch.events.PostJobExecutionHandler;
 
 class PostJobExecutionEvent extends AbstractPhaseEvent<PostJobExecutionHandler>
-    implements org.sonar.api.batch.events.PostJobExecutionHandler.PostJobExecutionEvent {
+  implements PostJobExecutionHandler.PostJobExecutionEvent {
 
   private final PostJob postJob;
 
index f3cfae99ae3d396f514499202d56b4341aeb42c6..033ec017d5eb540df81ff5756eb69ad4d8851c44 100644 (file)
  */
 package org.sonar.scanner.phases;
 
+import java.util.List;
 import org.sonar.api.batch.PostJob;
 import org.sonar.api.batch.events.PostJobsPhaseHandler;
 
-import java.util.List;
-
 class PostJobPhaseEvent extends AbstractPhaseEvent<PostJobsPhaseHandler>
-    implements org.sonar.api.batch.events.PostJobsPhaseHandler.PostJobsPhaseEvent {
+  implements PostJobsPhaseHandler.PostJobsPhaseEvent {
 
   private final List<PostJob> postJobs;
 
index feb427679ed030ece4c30ff2feee9730cb84ab49..aca9dc99bd7335fc053f0f11bdae264cc8a56f42 100644 (file)
@@ -23,7 +23,7 @@ import org.sonar.api.batch.events.ProjectAnalysisHandler;
 import org.sonar.api.resources.Project;
 
 class ProjectAnalysisEvent extends AbstractPhaseEvent<ProjectAnalysisHandler>
-    implements org.sonar.api.batch.events.ProjectAnalysisHandler.ProjectAnalysisEvent {
+  implements ProjectAnalysisHandler.ProjectAnalysisEvent {
 
   private final Project project;
 
index ebb1aeed3c12fb9c85fd184c93cfee60f9a0093f..1a9c203306a0a0b576c6c46b95addfb9a4e417a1 100644 (file)
@@ -23,7 +23,7 @@ import org.sonar.api.batch.Sensor;
 import org.sonar.api.batch.events.SensorExecutionHandler;
 
 class SensorExecutionEvent extends AbstractPhaseEvent<SensorExecutionHandler>
-    implements org.sonar.api.batch.events.SensorExecutionHandler.SensorExecutionEvent {
+  implements SensorExecutionHandler.SensorExecutionEvent {
 
   private final Sensor sensor;
 
index 17527ab195945de4da19ca5588efa435448ab706..f9464531d2d3353b18c654c0e9e7ee040653c18e 100644 (file)
@@ -22,7 +22,6 @@ package org.sonar.scanner.profiling;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -72,14 +71,8 @@ public abstract class AbstractTimeProfiling {
   }
 
   static <G extends AbstractTimeProfiling> Map<Object, G> sortByDescendingTotalTime(Map<?, G> unsorted) {
-    List<Map.Entry<?, G>> entries =
-        new ArrayList<Map.Entry<?, G>>(unsorted.entrySet());
-    Collections.sort(entries, new Comparator<Map.Entry<?, G>>() {
-      @Override
-      public int compare(Map.Entry<?, G> o1, Map.Entry<?, G> o2) {
-        return Long.valueOf(o2.getValue().totalTime()).compareTo(o1.getValue().totalTime());
-      }
-    });
+    List<Map.Entry<?, G>> entries = new ArrayList<>(unsorted.entrySet());
+    Collections.sort(entries, (o1, o2) -> Long.valueOf(o2.getValue().totalTime()).compareTo(o1.getValue().totalTime()));
     Map<Object, G> sortedMap = new LinkedHashMap<>();
     for (Map.Entry<?, G> entry : entries) {
       sortedMap.put(entry.getKey(), entry.getValue());
index d2fbf43761882bfa0c0b9344073d12db54079587..2a751aa04b42db24891d4a48e9ce3334374f5928 100644 (file)
  */
 package org.sonar.scanner.report;
 
-import com.google.common.base.Function;
-import com.google.common.collect.FluentIterable;
-import javax.annotation.Nonnull;
-import org.sonar.api.batch.rule.ActiveRule;
 import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.scanner.protocol.Constants;
 import org.sonar.scanner.protocol.output.ScannerReport;
 import org.sonar.scanner.protocol.output.ScannerReportWriter;
 
+import static java.util.stream.Collectors.toList;
+
 public class ActiveRulesPublisher implements ReportPublisherStep {
 
   private final ActiveRules activeRules;
@@ -38,21 +36,16 @@ public class ActiveRulesPublisher implements ReportPublisherStep {
 
   @Override
   public void publish(ScannerReportWriter writer) {
-    Iterable<ScannerReport.ActiveRule> activeRuleMessages = FluentIterable.from(activeRules.findAll()).transform(new ToMessage());
-    writer.writeActiveRules(activeRuleMessages);
+    final ScannerReport.ActiveRule.Builder builder = ScannerReport.ActiveRule.newBuilder();
+    writer.writeActiveRules(activeRules.findAll().stream()
+      .map(input -> {
+        builder.clear();
+        builder.setRuleRepository(input.ruleKey().repository());
+        builder.setRuleKey(input.ruleKey().rule());
+        builder.setSeverity(Constants.Severity.valueOf(input.severity()));
+        builder.getMutableParamsByKey().putAll(input.params());
+        return builder.build();
+      }).collect(toList()));
   }
 
-  private static class ToMessage implements Function<ActiveRule, ScannerReport.ActiveRule> {
-    private final ScannerReport.ActiveRule.Builder builder = ScannerReport.ActiveRule.newBuilder();
-
-    @Override
-    public ScannerReport.ActiveRule apply(@Nonnull ActiveRule input) {
-      builder.clear();
-      builder.setRuleRepository(input.ruleKey().repository());
-      builder.setRuleKey(input.ruleKey().rule());
-      builder.setSeverity(Constants.Severity.valueOf(input.severity()));
-      builder.getMutableParamsByKey().putAll(input.params());
-      return builder.build();
-    }
-  }
 }
index 4686aaea47a0714e3607e62807430f76bcc70ad6..33f58a8db3f8499cd901e7eecfdb26432b0333f3 100644 (file)
  */
 package org.sonar.scanner.report;
 
-import com.google.common.base.Function;
 import com.google.common.collect.Iterables;
 import java.io.Serializable;
 import java.util.Collections;
 import java.util.Map;
 import java.util.stream.StreamSupport;
-import javax.annotation.Nonnull;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.InputFile.Type;
 import org.sonar.api.batch.measure.Metric;
@@ -34,6 +32,7 @@ import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.test.MutableTestPlan;
 import org.sonar.api.test.TestCase.Status;
 import org.sonar.api.utils.KeyValueFormat;
+import org.sonar.core.util.stream.Collectors;
 import org.sonar.scanner.deprecated.test.TestPlanBuilder;
 import org.sonar.scanner.index.BatchComponent;
 import org.sonar.scanner.index.BatchComponentCache;
@@ -46,7 +45,6 @@ import org.sonar.scanner.protocol.output.ScannerReport.Measure.StringValue;
 import org.sonar.scanner.protocol.output.ScannerReportWriter;
 import org.sonar.scanner.scan.measure.MeasureCache;
 
-import static com.google.common.collect.Iterables.transform;
 import static org.sonar.api.measures.CoreMetrics.CONDITIONS_TO_COVER;
 import static org.sonar.api.measures.CoreMetrics.CONDITIONS_TO_COVER_KEY;
 import static org.sonar.api.measures.CoreMetrics.LINES_TO_COVER;
@@ -68,53 +66,6 @@ import static org.sonar.api.measures.CoreMetrics.UNCOVERED_LINES_KEY;
 
 public class MeasuresPublisher implements ReportPublisherStep {
 
-  private static final class MeasureToReportMeasure implements Function<DefaultMeasure, ScannerReport.Measure> {
-    private final BatchComponent resource;
-    private final ScannerReport.Measure.Builder builder = ScannerReport.Measure.newBuilder();
-
-    private MeasureToReportMeasure(BatchComponent resource) {
-      this.resource = resource;
-    }
-
-    @Override
-    public ScannerReport.Measure apply(@Nonnull DefaultMeasure input) {
-      validateMeasure(input, resource.key());
-      return toReportMeasure(builder, input);
-    }
-
-    private static void validateMeasure(DefaultMeasure measure, String componentKey) {
-      if (measure.value() == null) {
-        throw new IllegalArgumentException(String.format("Measure on metric '%s' and component '%s' has no value, but it's not allowed", measure.metric().key(), componentKey));
-      }
-    }
-
-    private static ScannerReport.Measure toReportMeasure(ScannerReport.Measure.Builder builder, DefaultMeasure measure) {
-      builder.clear();
-      builder.setMetricKey(measure.metric().key());
-      setValueAccordingToType(builder, measure);
-      return builder.build();
-    }
-
-    private static void setValueAccordingToType(ScannerReport.Measure.Builder builder, DefaultMeasure measure) {
-      Serializable value = measure.value();
-      Metric<?> metric = measure.metric();
-      if (Boolean.class.equals(metric.valueType())) {
-        builder.setBooleanValue(BoolValue.newBuilder().setValue(((Boolean) value).booleanValue()));
-      } else if (Integer.class.equals(metric.valueType())) {
-        builder.setIntValue(IntValue.newBuilder().setValue(((Number) value).intValue()));
-      } else if (Double.class.equals(metric.valueType())) {
-        builder.setDoubleValue(DoubleValue.newBuilder().setValue(((Number) value).doubleValue()));
-      } else if (String.class.equals(metric.valueType())) {
-        builder.setStringValue(StringValue.newBuilder().setValue((String) value));
-      } else if (Long.class.equals(metric.valueType())) {
-        builder.setLongValue(LongValue.newBuilder().setValue(((Number) value).longValue()));
-      } else {
-        throw new UnsupportedOperationException("Unsupported type :" + metric.valueType());
-      }
-    }
-
-  }
-
   private final BatchComponentCache componentCache;
   private final MeasureCache measureCache;
   private final TestPlanBuilder testPlanBuilder;
@@ -127,6 +78,8 @@ public class MeasuresPublisher implements ReportPublisherStep {
 
   @Override
   public void publish(ScannerReportWriter writer) {
+    final ScannerReport.Measure.Builder builder = ScannerReport.Measure.newBuilder();
+
     for (final BatchComponent component : componentCache.all()) {
       // Recompute all coverage measures from line data to take into account the possible merge of several reports
       updateCoverageFromLineData(component);
@@ -134,8 +87,35 @@ public class MeasuresPublisher implements ReportPublisherStep {
       updateTestExecutionFromTestPlan(component);
 
       Iterable<DefaultMeasure<?>> scannerMeasures = measureCache.byComponentKey(component.key());
-      Iterable<ScannerReport.Measure> reportMeasures = transform(scannerMeasures, new MeasureToReportMeasure(component));
-      writer.writeComponentMeasures(component.batchId(), reportMeasures);
+      writer.writeComponentMeasures(component.batchId(), StreamSupport.stream(scannerMeasures.spliterator(), false)
+        .map(input -> {
+          if (input.value() == null) {
+            throw new IllegalArgumentException(
+              String.format("Measure on metric '%s' and component '%s' has no value, but it's not allowed", input.metric().key(), component.key()));
+          }
+          builder.clear();
+          builder.setMetricKey(input.metric().key());
+          setValueAccordingToType(builder, input);
+          return builder.build();
+        }).collect(Collectors.toList()));
+    }
+  }
+
+  private static void setValueAccordingToType(ScannerReport.Measure.Builder builder, DefaultMeasure measure) {
+    Serializable value = measure.value();
+    Metric<?> metric = measure.metric();
+    if (Boolean.class.equals(metric.valueType())) {
+      builder.setBooleanValue(BoolValue.newBuilder().setValue(((Boolean) value).booleanValue()));
+    } else if (Integer.class.equals(metric.valueType())) {
+      builder.setIntValue(IntValue.newBuilder().setValue(((Number) value).intValue()));
+    } else if (Double.class.equals(metric.valueType())) {
+      builder.setDoubleValue(DoubleValue.newBuilder().setValue(((Number) value).doubleValue()));
+    } else if (String.class.equals(metric.valueType())) {
+      builder.setStringValue(StringValue.newBuilder().setValue((String) value));
+    } else if (Long.class.equals(metric.valueType())) {
+      builder.setLongValue(LongValue.newBuilder().setValue(((Number) value).longValue()));
+    } else {
+      throw new UnsupportedOperationException("Unsupported type :" + metric.valueType());
     }
   }
 
index d37c9439e8bc08b3e3a90d8c817f37621df75409..04ae3e824eb39ca7d3e8a246b37fa25e314321d2 100644 (file)
  */
 package org.sonar.scanner.report;
 
-import com.google.common.base.Function;
 import com.google.common.collect.Iterables;
 import java.util.HashSet;
 import java.util.Set;
-import javax.annotation.Nonnull;
+import java.util.stream.StreamSupport;
 import org.sonar.api.test.CoverageBlock;
 import org.sonar.api.test.MutableTestCase;
 import org.sonar.api.test.MutableTestPlan;
@@ -38,69 +37,9 @@ import org.sonar.scanner.protocol.output.ScannerReport.Test;
 import org.sonar.scanner.protocol.output.ScannerReport.Test.TestStatus;
 import org.sonar.scanner.protocol.output.ScannerReportWriter;
 
-public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {
-
-  private static final class TestConverter implements Function<MutableTestCase, ScannerReport.Test> {
-    private final Set<String> testNamesWithCoverage;
-    private ScannerReport.Test.Builder builder = ScannerReport.Test.newBuilder();
-
-    private TestConverter(Set<String> testNamesWithCoverage) {
-      this.testNamesWithCoverage = testNamesWithCoverage;
-    }
-
-    @Override
-    public Test apply(@Nonnull MutableTestCase testCase) {
-      builder.clear();
-      builder.setName(testCase.name());
-      if (testCase.doesCover()) {
-        testNamesWithCoverage.add(testCase.name());
-      }
-      Long durationInMs = testCase.durationInMs();
-      if (durationInMs != null) {
-        builder.setDurationInMs(durationInMs.longValue());
-      }
-      String msg = testCase.message();
-      if (msg != null) {
-        builder.setMsg(msg);
-      }
-      String stack = testCase.stackTrace();
-      if (stack != null) {
-        builder.setStacktrace(stack);
-      }
-      TestCase.Status status = testCase.status();
-      if (status != null) {
-        builder.setStatus(TestStatus.valueOf(status.name()));
-      }
-      return builder.build();
-    }
-  }
-
-  private final class TestCoverageConverter implements Function<String, CoverageDetail> {
-    private final MutableTestPlan testPlan;
-    private ScannerReport.CoverageDetail.Builder builder = ScannerReport.CoverageDetail.newBuilder();
-    private ScannerReport.CoverageDetail.CoveredFile.Builder coveredBuilder = ScannerReport.CoverageDetail.CoveredFile.newBuilder();
-
-    private TestCoverageConverter(MutableTestPlan testPlan) {
-      this.testPlan = testPlan;
-    }
+import static java.util.stream.Collectors.toList;
 
-    @Override
-    public CoverageDetail apply(@Nonnull String testName) {
-      // Take first test with provided name
-      MutableTestCase testCase = testPlan.testCasesByName(testName).iterator().next();
-      builder.clear();
-      builder.setTestName(testName);
-      for (CoverageBlock block : testCase.coverageBlocks()) {
-        coveredBuilder.clear();
-        coveredBuilder.setFileRef(componentCache.get(((DefaultTestable) block.testable()).inputFile().key()).batchId());
-        for (int line : block.lines()) {
-          coveredBuilder.addCoveredLine(line);
-        }
-        builder.addCoveredFile(coveredBuilder.build());
-      }
-      return builder.build();
-    }
-  }
+public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {
 
   private final BatchComponentCache componentCache;
   private final TestPlanBuilder testPlanBuilder;
@@ -112,6 +51,9 @@ public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {
 
   @Override
   public void publish(ScannerReportWriter writer) {
+    final ScannerReport.Test.Builder testBuilder = ScannerReport.Test.newBuilder();
+    final ScannerReport.CoverageDetail.Builder builder = ScannerReport.CoverageDetail.newBuilder();
+    final ScannerReport.CoverageDetail.CoveredFile.Builder coveredBuilder = ScannerReport.CoverageDetail.CoveredFile.newBuilder();
     for (final BatchComponent component : componentCache.all()) {
       final MutableTestPlan testPlan = testPlanBuilder.loadPerspective(MutableTestPlan.class, component.inputComponent());
       if (testPlan == null || Iterables.isEmpty(testPlan.testCases())) {
@@ -120,9 +62,56 @@ public class TestExecutionAndCoveragePublisher implements ReportPublisherStep {
 
       final Set<String> testNamesWithCoverage = new HashSet<>();
 
-      writer.writeTests(component.batchId(), Iterables.transform(testPlan.testCases(), new TestConverter(testNamesWithCoverage)));
+      writer.writeTests(component.batchId(),
+        StreamSupport.stream(testPlan.testCases().spliterator(), false)
+          .map(testCase -> toProtobufTest(testBuilder, testNamesWithCoverage, testCase))
+          .collect(toList()));
 
-      writer.writeCoverageDetails(component.batchId(), Iterables.transform(testNamesWithCoverage, new TestCoverageConverter(testPlan)));
+      writer.writeCoverageDetails(component.batchId(), testNamesWithCoverage.stream()
+        .map(testName -> toProtobufCoverageDetails(builder, coveredBuilder, testPlan, testName))
+        .collect(toList()));
+    }
+  }
+
+  private CoverageDetail toProtobufCoverageDetails(final ScannerReport.CoverageDetail.Builder builder, final ScannerReport.CoverageDetail.CoveredFile.Builder coveredBuilder,
+    final MutableTestPlan testPlan, String testName) {
+    // Take first test with provided name
+    MutableTestCase testCase = testPlan.testCasesByName(testName).iterator().next();
+    builder.clear();
+    builder.setTestName(testName);
+    for (CoverageBlock block : testCase.coverageBlocks()) {
+      coveredBuilder.clear();
+      coveredBuilder.setFileRef(componentCache.get(((DefaultTestable) block.testable()).inputFile().key()).batchId());
+      for (int line : block.lines()) {
+        coveredBuilder.addCoveredLine(line);
+      }
+      builder.addCoveredFile(coveredBuilder.build());
+    }
+    return builder.build();
+  }
+
+  private static Test toProtobufTest(final ScannerReport.Test.Builder testBuilder, final Set<String> testNamesWithCoverage, MutableTestCase testCase) {
+    testBuilder.clear();
+    testBuilder.setName(testCase.name());
+    if (testCase.doesCover()) {
+      testNamesWithCoverage.add(testCase.name());
+    }
+    Long durationInMs = testCase.durationInMs();
+    if (durationInMs != null) {
+      testBuilder.setDurationInMs(durationInMs.longValue());
+    }
+    String msg = testCase.message();
+    if (msg != null) {
+      testBuilder.setMsg(msg);
+    }
+    String stack = testCase.stackTrace();
+    if (stack != null) {
+      testBuilder.setStacktrace(stack);
+    }
+    TestCase.Status status = testCase.status();
+    if (status != null) {
+      testBuilder.setStatus(TestStatus.valueOf(status.name()));
     }
+    return testBuilder.build();
   }
 }
index cea4a21ba17ae3e47b586179df69c1e424417348..abdefcae436c15c4edec544975ce72726696974b 100644 (file)
 package org.sonar.scanner.repository;
 
 import com.google.common.base.Throwables;
-
 import com.google.common.collect.HashBasedTable;
 import com.google.common.collect.Table;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
 import java.util.Date;
 import java.util.Map;
-
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.utils.MessageException;
 import org.sonar.scanner.bootstrap.BatchWsClient;
 import org.sonar.scanner.util.BatchUtils;
+import org.sonarqube.ws.WsBatch;
 import org.sonarqube.ws.WsBatch.WsProjectResponse;
 import org.sonarqube.ws.WsBatch.WsProjectResponse.FileDataByPath;
 import org.sonarqube.ws.WsBatch.WsProjectResponse.Settings;
@@ -109,7 +107,7 @@ public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoad
 
       Map<String, FileDataByPath> fileDataByModuleAndPath = response.getFileDataByModuleAndPath();
       for (Map.Entry<String, FileDataByPath> e1 : fileDataByModuleAndPath.entrySet()) {
-        for (Map.Entry<String, org.sonarqube.ws.WsBatch.WsProjectResponse.FileData> e2 : e1.getValue().getFileDataByPath().entrySet()) {
+        for (Map.Entry<String, WsBatch.WsProjectResponse.FileData> e2 : e1.getValue().getFileDataByPath().entrySet()) {
           FileData fd = new FileData(e2.getValue().getHash(), e2.getValue().getRevision());
           fileDataTable.put(e1.getKey(), e2.getKey(), fd);
         }
index acff8ed90a1d840a82aa8b91d7a2d692d3554877..7df5a23f820d85fe1c9b4cff27e1914324a53ec6 100644 (file)
@@ -25,17 +25,17 @@ import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-
 import org.apache.commons.io.IOUtils;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.scanner.bootstrap.BatchWsClient;
 import org.sonar.scanner.util.BatchUtils;
+import org.sonarqube.ws.Rules;
 import org.sonarqube.ws.Rules.Active;
 import org.sonarqube.ws.Rules.Active.Param;
-import org.sonarqube.ws.client.GetRequest;
 import org.sonarqube.ws.Rules.ActiveList;
 import org.sonarqube.ws.Rules.Rule;
 import org.sonarqube.ws.Rules.SearchResponse;
+import org.sonarqube.ws.client.GetRequest;
 
 public class DefaultActiveRulesLoader implements ActiveRulesLoader {
   private static final String RULES_SEARCH_URL = "/api/rules/search.protobuf?f=repo,name,severity,lang,internalKey,templateKey,params,actives&activation=true";
@@ -112,7 +112,7 @@ public class DefaultActiveRulesLoader implements ActiveRulesLoader {
 
       Map<String, String> params = new HashMap<>();
 
-      for (org.sonarqube.ws.Rules.Rule.Param param : r.getParams().getParamsList()) {
+      for (Rules.Rule.Param param : r.getParams().getParamsList()) {
         params.put(param.getKey(), param.getDefaultValue());
       }
 
index 75c9e927cc043e993e07e2e647ae82e5abbe45a3..adb316b5669cc6ae168800112856345f89850af3 100644 (file)
@@ -35,7 +35,6 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -160,22 +159,19 @@ public class FileIndexer {
   private void indexFile(final InputFileBuilder inputFileBuilder, final DefaultModuleFileSystem fs,
     final Progress status, final DefaultInputFile inputFile, final InputFile.Type type) {
 
-    tasks.add(executorService.submit(new Callable<Void>() {
-      @Override
-      public Void call() {
-        DefaultInputFile completedInputFile = inputFileBuilder.completeAndComputeMetadata(inputFile, type);
-        if (completedInputFile != null && accept(completedInputFile)) {
-          fs.add(completedInputFile);
-          status.markAsIndexed(completedInputFile);
-          File parentDir = completedInputFile.file().getParentFile();
-          String relativePath = new PathResolver().relativePath(fs.baseDir(), parentDir);
-          if (relativePath != null) {
-            DefaultInputDir inputDir = new DefaultInputDir(fs.moduleKey(), relativePath);
-            fs.add(inputDir);
-          }
+    tasks.add(executorService.submit(() -> {
+      DefaultInputFile completedInputFile = inputFileBuilder.completeAndComputeMetadata(inputFile, type);
+      if (completedInputFile != null && accept(completedInputFile)) {
+        fs.add(completedInputFile);
+        status.markAsIndexed(completedInputFile);
+        File parentDir = completedInputFile.file().getParentFile();
+        String relativePath = new PathResolver().relativePath(fs.baseDir(), parentDir);
+        if (relativePath != null) {
+          DefaultInputDir inputDir = new DefaultInputDir(fs.moduleKey(), relativePath);
+          fs.add(inputDir);
         }
-        return null;
       }
+      return null;
     }));
 
   }
index 38de10c10318506aae1ecb176a4cb484da1fbf25..394c7d480ce07f949e3895c50cbd168f5a12dd9d 100644 (file)
@@ -21,13 +21,13 @@ package org.sonar.scanner.scan.measure;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import org.sonar.api.measures.Metric;
-import org.sonar.api.measures.Metric.ValueType;
-import org.sonar.scanner.protocol.input.GlobalRepositories;
-import org.sonar.api.measures.MetricFinder;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import org.sonar.api.measures.Metric;
+import org.sonar.api.measures.Metric.ValueType;
+import org.sonar.api.measures.MetricFinder;
+import org.sonar.scanner.protocol.input.GlobalRepositories;
 
 public final class DeprecatedMetricFinder implements MetricFinder {
 
@@ -36,7 +36,7 @@ public final class DeprecatedMetricFinder implements MetricFinder {
 
   public DeprecatedMetricFinder(GlobalRepositories globalReferentials) {
     for (org.sonar.scanner.protocol.input.Metric metric : globalReferentials.metrics()) {
-      Metric hibernateMetric = new org.sonar.api.measures.Metric.Builder(metric.key(), metric.name(), ValueType.valueOf(metric.valueType()))
+      Metric hibernateMetric = new Metric.Builder(metric.key(), metric.name(), ValueType.valueOf(metric.valueType()))
         .create()
         .setDirection(metric.direction())
         .setQualitative(metric.isQualitative())
@@ -47,7 +47,7 @@ public final class DeprecatedMetricFinder implements MetricFinder {
         .setWorstValue(metric.worstValue())
         .setId(metric.id());
       metricsByKey.put(metric.key(), hibernateMetric);
-      metricsById.put(metric.id(), new org.sonar.api.measures.Metric.Builder(metric.key(), metric.key(), ValueType.valueOf(metric.valueType())).create().setId(metric.id()));
+      metricsById.put(metric.id(), new Metric.Builder(metric.key(), metric.key(), ValueType.valueOf(metric.valueType())).create().setId(metric.id()));
     }
   }
 
index 908c5320e55a16cc961ca1d1fb6bccbfd398b081..218754a197d010f45bcb3893fe14bb3685c7339e 100644 (file)
@@ -20,8 +20,6 @@
 package org.sonar.scanner.sensor;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.collect.Iterables;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
@@ -32,7 +30,6 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-import javax.annotation.Nonnull;
 import org.sonar.api.batch.fs.InputComponent;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.TextRange;
@@ -43,7 +40,6 @@ import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
 import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
 import org.sonar.api.batch.sensor.error.AnalysisError;
 import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
-import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.batch.sensor.issue.Issue;
 import org.sonar.api.batch.sensor.measure.Measure;
@@ -70,6 +66,7 @@ import org.sonar.scanner.repository.ContextPropertiesCache;
 import org.sonar.scanner.scan.measure.MeasureCache;
 import org.sonar.scanner.sensor.coverage.CoverageExclusions;
 
+import static java.util.stream.Collectors.toList;
 import static org.sonar.api.measures.CoreMetrics.BRANCH_COVERAGE;
 import static org.sonar.api.measures.CoreMetrics.COMMENTED_OUT_CODE_LINES_KEY;
 import static org.sonar.api.measures.CoreMetrics.CONDITIONS_BY_LINE;
@@ -361,8 +358,20 @@ public class DefaultSensorStorage implements SensorStorage {
     if (writer.hasComponentData(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, componentRef)) {
       throw new UnsupportedOperationException("Trying to save highlighting twice for the same file is not supported: " + inputFile.absolutePath());
     }
+    final ScannerReport.SyntaxHighlightingRule.Builder builder = ScannerReport.SyntaxHighlightingRule.newBuilder();
+    final ScannerReport.TextRange.Builder rangeBuilder = ScannerReport.TextRange.newBuilder();
+
     writer.writeComponentSyntaxHighlighting(componentRef,
-      Iterables.transform(highlighting.getSyntaxHighlightingRuleSet(), new BuildSyntaxHighlighting()));
+      highlighting.getSyntaxHighlightingRuleSet().stream()
+        .map(input -> {
+          builder.setRange(rangeBuilder.setStartLine(input.range().start().line())
+            .setStartOffset(input.range().start().lineOffset())
+            .setEndLine(input.range().end().line())
+            .setEndOffset(input.range().end().lineOffset())
+            .build());
+          builder.setType(ScannerReportUtils.toProtocolType(input.getTextType()));
+          return builder.build();
+        }).collect(toList()));
   }
 
   @Override
@@ -372,13 +381,11 @@ public class DefaultSensorStorage implements SensorStorage {
     if (writer.hasComponentData(FileStructure.Domain.SYMBOLS, componentRef)) {
       throw new UnsupportedOperationException("Trying to save symbol table twice for the same file is not supported: " + symbolTable.inputFile().absolutePath());
     }
+    final ScannerReport.Symbol.Builder builder = ScannerReport.Symbol.newBuilder();
+    final ScannerReport.TextRange.Builder rangeBuilder = ScannerReport.TextRange.newBuilder();
     writer.writeComponentSymbols(componentRef,
-      Iterables.transform(symbolTable.getReferencesBySymbol().entrySet(), new Function<Map.Entry<TextRange, Set<TextRange>>, ScannerReport.Symbol>() {
-        private ScannerReport.Symbol.Builder builder = ScannerReport.Symbol.newBuilder();
-        private ScannerReport.TextRange.Builder rangeBuilder = ScannerReport.TextRange.newBuilder();
-
-        @Override
-        public ScannerReport.Symbol apply(Map.Entry<TextRange, Set<TextRange>> input) {
+      symbolTable.getReferencesBySymbol().entrySet().stream()
+        .map(input -> {
           builder.clear();
           rangeBuilder.clear();
           TextRange declaration = input.getKey();
@@ -395,9 +402,7 @@ public class DefaultSensorStorage implements SensorStorage {
               .build());
           }
           return builder.build();
-        }
-
-      }));
+        }).collect(Collectors.toList()));
   }
 
   @Override
@@ -424,22 +429,6 @@ public class DefaultSensorStorage implements SensorStorage {
     }
   }
 
-  private static class BuildSyntaxHighlighting implements Function<SyntaxHighlightingRule, ScannerReport.SyntaxHighlightingRule> {
-    private ScannerReport.SyntaxHighlightingRule.Builder builder = ScannerReport.SyntaxHighlightingRule.newBuilder();
-    private ScannerReport.TextRange.Builder rangeBuilder = ScannerReport.TextRange.newBuilder();
-
-    @Override
-    public ScannerReport.SyntaxHighlightingRule apply(@Nonnull SyntaxHighlightingRule input) {
-      builder.setRange(rangeBuilder.setStartLine(input.range().start().line())
-        .setStartOffset(input.range().start().lineOffset())
-        .setEndLine(input.range().end().line())
-        .setEndOffset(input.range().end().lineOffset())
-        .build());
-      builder.setType(ScannerReportUtils.toProtocolType(input.getTextType()));
-      return builder.build();
-    }
-  }
-
   @Override
   public void store(DefaultCpdTokens defaultCpdTokens) {
     InputFile inputFile = defaultCpdTokens.inputFile();
index 565525067dd2cee83e1939013dcbd090e76fdad5..357ae80d80117f3317b90846910d5ceebec66ade 100644 (file)
@@ -81,14 +81,14 @@ public class DefaultHighlightable implements Highlightable {
 
     @Override
     public HighlightingBuilder highlight(int startOffset, int endOffset, String typeOfText) {
-      TypeOfText type = org.sonar.api.batch.sensor.highlighting.TypeOfText.forCssClass(typeOfText);
+      TypeOfText type = TypeOfText.forCssClass(typeOfText);
       defaultHighlighting.highlight(startOffset, endOffset, type);
       return this;
     }
 
     @Override
     public HighlightingBuilder highlight(int startLine, int startLineOffset, int endLine, int endLineOffset, String typeOfText) {
-      TypeOfText type = org.sonar.api.batch.sensor.highlighting.TypeOfText.forCssClass(typeOfText);
+      TypeOfText type = TypeOfText.forCssClass(typeOfText);
       defaultHighlighting.highlight(startLine, startLineOffset, endLine, endLineOffset, type);
       return this;
     }
index 24d1023ade20232de6ea78e3786415c098c584cd..621870c4c2fce89a5d4dea59a2c696fa26d77386 100644 (file)
@@ -28,15 +28,19 @@ import java.util.List;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
-import org.sonar.api.config.Settings;
 import org.sonar.api.config.MapSettings;
+import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.core.util.CloseableIterator;
+import org.sonar.duplications.block.Block;
+import org.sonar.duplications.block.ByteArray;
 import org.sonar.duplications.index.CloneGroup;
 import org.sonar.duplications.index.ClonePart;
 import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
@@ -65,22 +69,25 @@ public class CpdExecutorTest {
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
 
-  // private AbstractCpdEngine engine;
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
 
   private ScannerReportReader reader;
   private BatchComponent batchComponent1;
   private BatchComponent batchComponent2;
   private BatchComponent batchComponent3;
+  private File baseDir;
 
   @Before
   public void setUp() throws IOException {
     File outputDir = temp.newFolder();
+    baseDir = temp.newFolder();
 
     settings = new MapSettings();
-    index = mock(SonarCpdBlockIndex.class);
     publisher = mock(ReportPublisher.class);
     when(publisher.getWriter()).thenReturn(new ScannerReportWriter(outputDir));
     componentCache = new BatchComponentCache();
+    index = new SonarCpdBlockIndex(publisher, componentCache, settings);
     executor = new CpdExecutor(settings, index, publisher, componentCache);
     reader = new ScannerReportReader(outputDir);
 
@@ -94,7 +101,10 @@ public class CpdExecutorTest {
 
   private BatchComponent createComponent(String relativePath, int lines) {
     org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("relativePath").setEffectiveKey("foo:" + relativePath);
-    return componentCache.add(sampleFile, null).setInputComponent(new DefaultInputFile("foo", relativePath).setLines(lines));
+    return componentCache.add(sampleFile, null)
+      .setInputComponent(new DefaultInputFile("foo", relativePath)
+        .setModuleBaseDir(baseDir.toPath())
+        .setLines(lines));
   }
 
   @Test
@@ -197,6 +207,39 @@ public class CpdExecutorTest {
     assertDuplication(dups[1], 15, 214, batchComponent3.batchId(), 15, 214);
   }
 
+  @Test
+  public void failOnMissingComponent() {
+    executor.runCpdAnalysis(null, "unknown", Collections.emptyList(), 1);
+    readDuplications(0);
+    assertThat(logTester.logs(LoggerLevel.ERROR)).contains("Resource not found in component cache: unknown. Skipping CPD computation for it");
+  }
+
+  @Test
+  public void timeout() {
+    for (int i = 1; i <= 2; i++) {
+      BatchComponent component = createComponent("src/Foo" + i + ".php", 100);
+      List<Block> blocks = new ArrayList<>();
+      for (int j = 1; j <= 100000; j++) {
+        blocks.add(Block.builder()
+          .setResourceId(component.key())
+          .setIndexInFile(j)
+          .setLines(j, j + 1)
+          .setUnit(j, j + 1)
+          .setBlockHash(new ByteArray("abcd1234".getBytes()))
+          .build());
+      }
+      index.insert((InputFile) component.inputComponent(), blocks);
+    }
+    executor.execute(1);
+
+    readDuplications(0);
+    assertThat(logTester.logs(LoggerLevel.WARN))
+      .usingElementComparator((l, r) -> l.matches(r) ? 0 : 1)
+      .containsOnly(
+        "Timeout during detection of duplications for .*Foo1.php",
+        "Timeout during detection of duplications for .*Foo2.php");
+  }
+
   private Duplication[] readDuplications(int expected) {
     assertThat(reader.readComponentDuplications(batchComponent1.batchId())).hasSize(expected);
     Duplication[] duplications = new Duplication[expected];