aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2017-03-01 15:33:22 +0100
committerSimon Brandhof <simon.brandhof@sonarsource.com>2017-03-01 16:52:54 +0100
commit72ac5447a32d6537e805374116cbf369f7a65038 (patch)
tree7f74cc6a6d8ba4b733162f750e449ba7581a010a
parent187e582f89cc4ba48e7078abe16e8869e69b9e36 (diff)
downloadsonarqube-72ac5447a32d6537e805374116cbf369f7a65038.tar.gz
sonarqube-72ac5447a32d6537e805374116cbf369f7a65038.zip
SONAR-8835 support NULL in column file_sources.line_hashes
The column can be null on Oracle if source content is empty. Other databases do not store NULL but empty string.
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStep.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileSimilarity.java11
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileSimilarityImpl.java15
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/SourceSimilarityImpl.java7
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest.java31
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/MatchesByScoreTest.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/SourceSimilarityImplTest.java8
7 files changed, 49 insertions, 33 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStep.java
index 182e4232455..df6c144f05f 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStep.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStep.java
@@ -56,6 +56,7 @@ import org.sonar.server.computation.task.projectanalysis.filemove.FileSimilarity
import org.sonar.server.computation.task.projectanalysis.source.SourceLinesRepository;
import org.sonar.server.computation.task.step.ComputationStep;
+import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Splitter.on;
import static com.google.common.collect.FluentIterable.from;
import static java.util.Arrays.asList;
@@ -233,7 +234,8 @@ public class FileMoveDetectionStep implements ComputationStep {
if (fileSourceDto == null) {
return null;
}
- return new File(dbComponent.getPath(), LINES_HASHES_SPLITTER.splitToList(fileSourceDto.getLineHashes()));
+ String lineHashes = firstNonNull(fileSourceDto.getLineHashes(), "");
+ return new File(dbComponent.getPath(), LINES_HASHES_SPLITTER.splitToList(lineHashes));
}
private static void printIfDebug(ScoreMatrix scoreMatrix) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileSimilarity.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileSimilarity.java
index 86743b06906..7f3547b904e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileSimilarity.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileSimilarity.java
@@ -20,8 +20,6 @@
package org.sonar.server.computation.task.projectanalysis.filemove;
import java.util.List;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
import static java.util.Objects.requireNonNull;
@@ -31,16 +29,19 @@ public interface FileSimilarity {
private final String path;
private final List<String> lineHashes;
- public File(String path, @Nullable List<String> lineHashes) {
+ public File(String path, List<String> lineHashes) {
this.path = requireNonNull(path, "path can not be null");
- this.lineHashes = lineHashes;
+ this.lineHashes = requireNonNull(lineHashes, "lineHashes can not be null");
}
public String getPath() {
return path;
}
- @CheckForNull
+ /**
+ * List of hash of each line. An empty list is returned
+ * if file content is empty.
+ */
public List<String> getLineHashes() {
return lineHashes;
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileSimilarityImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileSimilarityImpl.java
index c34bf8c1564..d059c0ac182 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileSimilarityImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/FileSimilarityImpl.java
@@ -19,8 +19,6 @@
*/
package org.sonar.server.computation.task.projectanalysis.filemove;
-import java.util.List;
-
public class FileSimilarityImpl implements FileSimilarity {
private final SourceSimilarity sourceSimilarity;
@@ -31,15 +29,10 @@ public class FileSimilarityImpl implements FileSimilarity {
@Override
public int score(File file1, File file2) {
- int score = 0;
-
- // TODO check filenames
+ // Algorithm could be improved by increasing score
+ // depending on filename similarity
+ // Current implementation relies on file content only.
- List<String> lineHashes1 = file1.getLineHashes();
- List<String> lineHashes2 = file2.getLineHashes();
- if (lineHashes1 != null && lineHashes2 != null) {
- score += sourceSimilarity.score(lineHashes1, lineHashes2);
- }
- return score;
+ return sourceSimilarity.score(file1.getLineHashes(), file2.getLineHashes());
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/SourceSimilarityImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/SourceSimilarityImpl.java
index bb9da71e5ef..bdbc91d3b25 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/SourceSimilarityImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/filemove/SourceSimilarityImpl.java
@@ -27,12 +27,15 @@ import static java.lang.Math.min;
public class SourceSimilarityImpl implements SourceSimilarity {
@Override
- public <T extends Object> int score(List<T> left, List<T> right) {
+ public <T> int score(List<T> left, List<T> right) {
+ if (left.isEmpty() && right.isEmpty()) {
+ return 0;
+ }
int distance = levenshteinDistance(left, right);
return (int) (100 * (1.0 - ((double) distance) / (max(left.size(), right.size()))));
}
- <T extends Object> int levenshteinDistance(List<T> left, List<T> right) {
+ private static <T> int levenshteinDistance(List<T> left, List<T> right) {
int len0 = left.size() + 1;
int len1 = right.size() + 1;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest.java
index 6f67fd94847..68af5bc8837 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/FileMoveDetectionStepTest.java
@@ -23,13 +23,12 @@ import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
+import javax.annotation.Nullable;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
@@ -410,6 +409,18 @@ public class FileMoveDetectionStepTest {
}
@Test
+ public void execute_detects_no_move_if_two_files_are_empty() {
+ analysisMetadataHolder.setBaseAnalysis(ANALYSIS);
+ mockComponents(FILE_1.getKey(), FILE_2.getKey());
+ mockContentOfFileInDb(FILE_1.getKey(), null);
+ mockContentOfFileInDb(FILE_2.getKey(), null);
+
+ underTest.execute();
+
+ assertThat(movedFilesRepository.getComponentsWithOriginal()).isEmpty();
+ }
+
+ @Test
public void execute_detects_several_moves() {
// testing:
// - file1 renamed to file3
@@ -496,17 +507,15 @@ public class FileMoveDetectionStepTest {
sourceLinesRepository.addLines(ref, content);
}
- private void mockContentOfFileInDb(String key, String[] content) {
- SourceLinesHashesComputer linesHashesComputer = new SourceLinesHashesComputer();
- Iterator<String> lineIterator = Arrays.asList(content).iterator();
- while (lineIterator.hasNext()) {
- String line = lineIterator.next();
- linesHashesComputer.addLine(line);
+ private void mockContentOfFileInDb(String key, @Nullable String[] content) {
+ FileSourceDto dto = new FileSourceDto();
+ if (content != null) {
+ SourceLinesHashesComputer linesHashesComputer = new SourceLinesHashesComputer();
+ stream(content).forEach(linesHashesComputer::addLine);
+ dto.setLineHashes(on('\n').join(linesHashesComputer.getLineHashes()));
}
- when(fileSourceDao.selectSourceByFileUuid(dbSession, componentUuidOf(key)))
- .thenReturn(new FileSourceDto()
- .setLineHashes(on('\n').join(linesHashesComputer.getLineHashes())));
+ when(fileSourceDao.selectSourceByFileUuid(dbSession, componentUuidOf(key))).thenReturn(dto);
}
private void setFilesInReport(Component... files) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/MatchesByScoreTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/MatchesByScoreTest.java
index cbd96aac878..4007a357a7c 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/MatchesByScoreTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/MatchesByScoreTest.java
@@ -30,6 +30,8 @@ import java.util.Set;
import org.junit.Test;
import static com.google.common.collect.ImmutableSet.of;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptySet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.server.computation.task.projectanalysis.filemove.FileMoveDetectionStep.MIN_REQUIRED_SCORE;
@@ -39,7 +41,7 @@ public class MatchesByScoreTest {
@Test
public void creates_returns_always_the_same_instance_of_maxScore_is_less_than_min_required_score() {
- Set<String> doesNotMatterDbFileKeys = Collections.emptySet();
+ Set<String> doesNotMatterDbFileKeys = emptySet();
Map<String, FileSimilarity.File> doesNotMatterReportFiles = Collections.emptyMap();
int[][] doesNotMatterScores = new int[0][0];
@@ -78,6 +80,6 @@ public class MatchesByScoreTest {
}
private static FileSimilarity.File fileOf(String key) {
- return new FileSimilarity.File("path of " + key, null);
+ return new FileSimilarity.File("path of " + key, emptyList());
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/SourceSimilarityImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/SourceSimilarityImplTest.java
index 1c50bddbdb5..11ae0481655 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/SourceSimilarityImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/filemove/SourceSimilarityImplTest.java
@@ -25,6 +25,7 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
public class SourceSimilarityImplTest {
@@ -32,7 +33,7 @@ public class SourceSimilarityImplTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
- SourceSimilarityImpl underTest = new SourceSimilarityImpl();
+ private SourceSimilarityImpl underTest = new SourceSimilarityImpl();
@Test
public void zero_if_fully_different() {
@@ -53,4 +54,9 @@ public class SourceSimilarityImplTest {
assertThat(underTest.score(asList("a"), asList("a", "b", "c"))).isEqualTo(33);
assertThat(underTest.score(asList("a", "b", "c"), asList("a"))).isEqualTo(33);
}
+
+ @Test
+ public void two_empty_lists_are_not_considered_as_equal() {
+ assertThat(underTest.score(emptyList(), emptyList())).isEqualTo(0);
+ }
}