]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12802 SONAR-12927 Fix moved file detection for cobol and when calculating new...
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Wed, 29 Jan 2020 16:06:07 +0000 (10:06 -0600)
committerSonarTech <sonartech@sonarsource.com>
Fri, 14 Feb 2020 19:53:09 +0000 (20:53 +0100)
25 files changed:
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/filemove/FileMoveDetectionStep.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/filemove/FileSimilarity.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/filemove/MovedFilesRepository.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/filemove/MutableMovedFilesRepositoryImpl.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ClosedIssuesInputFactory.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/MovedIssueVisitor.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/RemoveProcessedComponentsVisitor.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerBaseInputFactory.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoader.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/DbLineHashVersion.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/PersistFileSourcesStep.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/SourceLinesDiffImpl.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/SourceLinesHashRepositoryImpl.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/filemove/MutableMovedFilesRepositoryImplTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/filemove/MutableMovedFilesRepositoryRule.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ClosedIssuesInputFactoryTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/MovedIssueVisitorTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/RemoveProcessedComponentsVisitorTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TrackerBaseInputFactoryTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoaderTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/SourceLinesDiffImplTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/SourceLinesHashRepositoryImplTest.java
server/sonar-db-dao/src/main/java/org/sonar/db/source/FileSourceDao.java
server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java

index b814b565ce78ef9975f5905810be016c3488339d..5d3a8ab4d3429b487ab683030575a4bb21dc557b 100644 (file)
@@ -26,6 +26,7 @@ import com.google.common.collect.Multimap;
 import com.google.common.collect.Sets;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -33,6 +34,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.Immutable;
 import org.apache.ibatis.session.ResultContext;
@@ -57,7 +59,6 @@ import org.sonar.db.DbSession;
 import org.sonar.db.component.FileMoveRowDto;
 import org.sonar.db.source.LineHashesWithUuidDto;
 
-import static com.google.common.collect.FluentIterable.from;
 import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER;
 
 public class FileMoveDetectionStep implements ComputationStep {
@@ -125,7 +126,7 @@ public class FileMoveDetectionStep implements ComputationStep {
 
     Set<String> removedFileUuids = difference(dbFilesByUuid.keySet(), reportFilesByUuid.keySet());
 
-    // can find matches if at least one of the added or removed files groups is empty => abort
+    // can't find matches if at least one of the added or removed files groups is empty => abort
     if (addedFileUuids.isEmpty() || removedFileUuids.isEmpty()) {
       registerAddedFiles(addedFileUuids, reportFilesByUuid, null);
       LOG.debug("Either no files added or no files removed. Do nothing.");
@@ -133,12 +134,12 @@ public class FileMoveDetectionStep implements ComputationStep {
     }
 
     // retrieve file data from report
-    Map<String, File> reportFileSourcesByUuid = getReportFileSourcesByUuid(reportFilesByUuid, addedFileUuids);
+    Map<String, File> addedFileHashesByUuid = getReportFileHashesByUuid(reportFilesByUuid, addedFileUuids);
     p.stopTrace("loaded");
 
     // compute score matrix
     p.start();
-    ScoreMatrix scoreMatrix = computeScoreMatrix(dbFilesByUuid, removedFileUuids, reportFileSourcesByUuid);
+    ScoreMatrix scoreMatrix = computeScoreMatrix(dbFilesByUuid, removedFileUuids, addedFileHashesByUuid);
     p.stopTrace("Score matrix computed");
     scoreMatrixDumper.dumpAsCsv(scoreMatrix);
 
@@ -153,7 +154,7 @@ public class FileMoveDetectionStep implements ComputationStep {
     p.start();
     MatchesByScore matchesByScore = MatchesByScore.create(scoreMatrix);
 
-    ElectedMatches electedMatches = electMatches(removedFileUuids, reportFileSourcesByUuid, matchesByScore);
+    ElectedMatches electedMatches = electMatches(removedFileUuids, addedFileHashesByUuid, matchesByScore);
     p.stopTrace("Matches elected");
 
     context.getStatistics().add("movedFiles", electedMatches.size());
@@ -219,25 +220,21 @@ public class FileMoveDetectionStep implements ComputationStep {
     return builder.build();
   }
 
-  private Map<String, File> getReportFileSourcesByUuid(Map<String, Component> reportFilesByUuid, Set<String> addedFileUuids) {
-    ImmutableMap.Builder<String, File> builder = ImmutableMap.builder();
-    for (String fileUuid : addedFileUuids) {
+  private Map<String, File> getReportFileHashesByUuid(Map<String, Component> reportFilesByUuid, Set<String> addedFileUuids) {
+    return addedFileUuids.stream().collect(Collectors.toMap(fileUuid -> fileUuid, fileUuid -> {
       Component component = reportFilesByUuid.get(fileUuid);
-      File file = new LazyFileImpl(
-        component.getName(),
-        () -> getReportFileLineHashes(component),
-        component.getFileAttributes().getLines());
-      builder.put(fileUuid, file);
-    }
-    return builder.build();
+      return new LazyFileImpl(() -> getReportFileLineHashes(component), component.getFileAttributes().getLines());
+    }));
   }
 
   private List<String> getReportFileLineHashes(Component component) {
+    // this is not ideal because if the file moved, this component won't exist in DB with the same UUID.
+    // Assuming that the file also had significant code before the move, it will be fine.
     return sourceLinesHash.getLineHashesMatchingDBVersion(component);
   }
 
-  private ScoreMatrix computeScoreMatrix(Map<String, DbComponent> dtosByUuid, Set<String> removedFileUuids, Map<String, File> newFileSourcesByUuid) {
-    ScoreMatrix.ScoreFile[] newFiles = newFileSourcesByUuid.entrySet().stream()
+  private ScoreMatrix computeScoreMatrix(Map<String, DbComponent> dtosByUuid, Set<String> removedFileUuids, Map<String, File> addedFileHashesByUuid) {
+    ScoreMatrix.ScoreFile[] addedFiles = addedFileHashesByUuid.entrySet().stream()
       .map(e -> new ScoreMatrix.ScoreFile(e.getKey(), e.getValue().getLineCount()))
       .toArray(ScoreMatrix.ScoreFile[]::new);
     ScoreMatrix.ScoreFile[] removedFiles = removedFileUuids.stream()
@@ -246,48 +243,50 @@ public class FileMoveDetectionStep implements ComputationStep {
         return new ScoreMatrix.ScoreFile(dbComponent.getUuid(), dbComponent.getLineCount());
       })
       .toArray(ScoreMatrix.ScoreFile[]::new);
+
     // sort by highest line count first
-    Arrays.sort(newFiles, SCORE_FILE_COMPARATOR);
+    Arrays.sort(addedFiles, SCORE_FILE_COMPARATOR);
     Arrays.sort(removedFiles, SCORE_FILE_COMPARATOR);
-    int[][] scoreMatrix = new int[removedFiles.length][newFiles.length];
-    int lastNewFileIndex = newFiles.length - 1;
+    int[][] scoreMatrix = new int[removedFiles.length][addedFiles.length];
+    int smallestAddedFileSize = addedFiles[0].getLineCount();
+    int largestAddedFileSize = addedFiles[addedFiles.length - 1].getLineCount();
 
-    Map<String, Integer> removedFilesIndexes = new HashMap<>(removedFileUuids.size());
+    Map<String, Integer> removedFilesIndexesByUuid = new HashMap<>(removedFileUuids.size());
     for (int removeFileIndex = 0; removeFileIndex < removedFiles.length; removeFileIndex++) {
       ScoreMatrix.ScoreFile removedFile = removedFiles[removeFileIndex];
       int lowerBound = (int) Math.floor(removedFile.getLineCount() * LOWER_BOUND_RATIO);
       int upperBound = (int) Math.ceil(removedFile.getLineCount() * UPPER_BOUND_RATIO);
       // no need to compute score if all files are out of bound, so no need to load line hashes from DB
-      if (newFiles[0].getLineCount() <= lowerBound || newFiles[lastNewFileIndex].getLineCount() >= upperBound) {
+      if (smallestAddedFileSize <= lowerBound || largestAddedFileSize >= upperBound) {
         continue;
       }
-      removedFilesIndexes.put(removedFile.getFileUuid(), removeFileIndex);
+      removedFilesIndexesByUuid.put(removedFile.getFileUuid(), removeFileIndex);
     }
 
-    LineHashesWithKeyDtoResultHandler rowHandler = new LineHashesWithKeyDtoResultHandler(removedFilesIndexes, removedFiles,
-      newFiles, newFileSourcesByUuid, scoreMatrix);
+    LineHashesWithKeyDtoResultHandler rowHandler = new LineHashesWithKeyDtoResultHandler(removedFilesIndexesByUuid, removedFiles,
+      addedFiles, addedFileHashesByUuid, scoreMatrix);
     try (DbSession dbSession = dbClient.openSession(false)) {
-      dbClient.fileSourceDao().scrollLineHashes(dbSession, removedFilesIndexes.keySet(), rowHandler);
+      dbClient.fileSourceDao().scrollLineHashes(dbSession, removedFilesIndexesByUuid.keySet(), rowHandler);
     }
 
-    return new ScoreMatrix(removedFiles, newFiles, scoreMatrix, rowHandler.getMaxScore());
+    return new ScoreMatrix(removedFiles, addedFiles, scoreMatrix, rowHandler.getMaxScore());
   }
 
   private final class LineHashesWithKeyDtoResultHandler implements ResultHandler<LineHashesWithUuidDto> {
-    private final Map<String, Integer> removedFilesIndexes;
+    private final Map<String, Integer> removedFileIndexesByUuid;
     private final ScoreMatrix.ScoreFile[] removedFiles;
     private final ScoreMatrix.ScoreFile[] newFiles;
-    private final Map<String, File> newFileSourcesByKey;
+    private final Map<String, File> newFilesByUuid;
     private final int[][] scoreMatrix;
     private int maxScore;
 
-    private LineHashesWithKeyDtoResultHandler(Map<String, Integer> removedFilesIndexes, ScoreMatrix.ScoreFile[] removedFiles,
-      ScoreMatrix.ScoreFile[] newFiles, Map<String, File> newFileSourcesByKey,
+    private LineHashesWithKeyDtoResultHandler(Map<String, Integer> removedFileIndexesByUuid, ScoreMatrix.ScoreFile[] removedFiles,
+      ScoreMatrix.ScoreFile[] newFiles, Map<String, File> newFilesByUuid,
       int[][] scoreMatrix) {
-      this.removedFilesIndexes = removedFilesIndexes;
+      this.removedFileIndexesByUuid = removedFileIndexesByUuid;
       this.removedFiles = removedFiles;
       this.newFiles = newFiles;
-      this.newFileSourcesByKey = newFileSourcesByKey;
+      this.newFilesByUuid = newFilesByUuid;
       this.scoreMatrix = scoreMatrix;
     }
 
@@ -297,8 +296,8 @@ public class FileMoveDetectionStep implements ComputationStep {
       if (lineHashesDto.getPath() == null) {
         return;
       }
-      int removeFileIndex = removedFilesIndexes.get(lineHashesDto.getUuid());
-      ScoreMatrix.ScoreFile removedFile = removedFiles[removeFileIndex];
+      int removedFileIndex = removedFileIndexesByUuid.get(lineHashesDto.getUuid());
+      ScoreMatrix.ScoreFile removedFile = removedFiles[removedFileIndex];
       int lowerBound = (int) Math.floor(removedFile.getLineCount() * LOWER_BOUND_RATIO);
       int upperBound = (int) Math.ceil(removedFile.getLineCount() * UPPER_BOUND_RATIO);
 
@@ -311,10 +310,10 @@ public class FileMoveDetectionStep implements ComputationStep {
           break;
         }
 
-        File fileInDb = new FileImpl(lineHashesDto.getPath(), lineHashesDto.getLineHashes());
-        File unmatchedFile = newFileSourcesByKey.get(newFile.getFileUuid());
-        int score = fileSimilarity.score(fileInDb, unmatchedFile);
-        scoreMatrix[removeFileIndex][newFileIndex] = score;
+        File fileHashesInDb = new FileImpl(lineHashesDto.getLineHashes());
+        File unmatchedFile = newFilesByUuid.get(newFile.getFileUuid());
+        int score = fileSimilarity.score(fileHashesInDb, unmatchedFile);
+        scoreMatrix[removedFileIndex][newFileIndex] = score;
         if (score > maxScore) {
           maxScore = score;
         }
@@ -408,9 +407,9 @@ public class FileMoveDetectionStep implements ComputationStep {
     private final List<Match> matches;
     private final Set<String> matchedFileUuids;
 
-    public ElectedMatches(MatchesByScore matchesByScore, Set<String> dbFileUuids, Map<String, File> reportFileSourcesByUuid) {
+    public ElectedMatches(MatchesByScore matchesByScore, Set<String> dbFileUuids, Map<String, File> reportFileHashesByUuid) {
       this.matches = new ArrayList<>(matchesByScore.getSize());
-      this.matchedFileUuids = new HashSet<>(dbFileUuids.size() + reportFileSourcesByUuid.size());
+      this.matchedFileUuids = new HashSet<>(dbFileUuids.size() + reportFileHashesByUuid.size());
     }
 
     public void add(Match match) {
@@ -419,8 +418,8 @@ public class FileMoveDetectionStep implements ComputationStep {
       matchedFileUuids.add(match.getReportUuid());
     }
 
-    public List<Match> filter(Iterable<Match> matches) {
-      return from(matches).filter(this::notAlreadyMatched).toList();
+    public List<Match> filter(Collection<Match> matches) {
+      return matches.stream().filter(this::notAlreadyMatched).collect(Collectors.toList());
     }
 
     private boolean notAlreadyMatched(Match input) {
index e32d17bd01df017eff23e974db49bef4b1b746fb..ca6c4dc477744288e6af8d17c06afa3f221d960e 100644 (file)
@@ -29,28 +29,20 @@ import static java.util.Objects.requireNonNull;
 public interface FileSimilarity {
 
   interface File {
-    String getPath();
-
     List<String> getLineHashes();
 
     int getLineCount();
   }
 
   final class FileImpl implements File {
-    private final String path;
     private final List<String> lineHashes;
     private final int lineCount;
 
-    FileImpl(String path, List<String> lineHashes) {
-      this.path = requireNonNull(path, "path can not be null");
+    FileImpl(List<String> lineHashes) {
       this.lineHashes = requireNonNull(lineHashes, "lineHashes can not be null");
       this.lineCount = lineHashes.size();
     }
 
-    public String getPath() {
-      return path;
-    }
-
     /**
      * List of hash of each line. An empty list is returned
      * if file content is empty.
@@ -65,21 +57,15 @@ public interface FileSimilarity {
   }
 
   final class LazyFileImpl implements File {
-    private final String path;
     private final Supplier<List<String>> supplier;
     private final int lineCount;
     private List<String> lineHashes;
 
-    LazyFileImpl(String path, Supplier<List<String>> supplier, int lineCount) {
-      this.path = requireNonNull(path, "path can not be null");
+    LazyFileImpl(Supplier<List<String>> supplier, int lineCount) {
       this.supplier = requireNonNull(supplier, "supplier can not be null");
       this.lineCount = lineCount;
     }
 
-    public String getPath() {
-      return path;
-    }
-
     /**
      * List of hash of each line. An empty list is returned
      * if file content is empty.
index b45958e3a0c3b7b8ff385480626ad0c2742d8ba4..7e1ed629c514fdd0a63674e07814a7307ab9959b 100644 (file)
@@ -19,7 +19,7 @@
  */
 package org.sonar.ce.task.projectanalysis.filemove;
 
-import com.google.common.base.Optional;
+import java.util.Optional;
 import javax.annotation.Nullable;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.component.Component;
@@ -30,7 +30,7 @@ public interface MovedFilesRepository {
   /**
    * The original file for the specified component if it was registered as a moved file in the repository.
    * <p>
-   * Calling this method with a Component which is not a file, will always return {@link Optional#absent()}.
+   * Calling this method with a Component which is not a file, will always return {@link Optional#empty()}.
    * </p>
    */
   Optional<OriginalFile> getOriginalFile(Component file);
index 02c1cded3ce8180d9267753aeabcf15bbb9134e8..2822f7a13507c808a8775f4a5f2c5cb94ae8f76b 100644 (file)
@@ -19,9 +19,9 @@
  */
 package org.sonar.ce.task.projectanalysis.filemove;
 
-import com.google.common.base.Optional;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 import org.sonar.ce.task.projectanalysis.component.Component;
 
 import static com.google.common.base.Preconditions.checkArgument;
@@ -49,9 +49,9 @@ public class MutableMovedFilesRepositoryImpl implements MutableMovedFilesReposit
   public Optional<OriginalFile> getOriginalFile(Component file) {
     requireNonNull(file, "file can't be null");
     if (file.getType() != Component.Type.FILE) {
-      return Optional.absent();
+      return Optional.empty();
     }
 
-    return Optional.fromNullable(originalFiles.get(file.getDbKey()));
+    return Optional.ofNullable(originalFiles.get(file.getDbKey()));
   }
 }
index 924aff2ea168160d5abca1ed842ef076067fb83e..95e7e2c0654708641536cc06b6b5264e7ac88464 100644 (file)
@@ -39,7 +39,7 @@ public class ClosedIssuesInputFactory extends BaseInputFactory {
   }
 
   public Input<DefaultIssue> create(Component component) {
-    return new ClosedIssuesLazyInput(dbClient, component, movedFilesRepository.getOriginalFile(component).orNull());
+    return new ClosedIssuesLazyInput(dbClient, component, movedFilesRepository.getOriginalFile(component).orElse(null));
   }
 
   private class ClosedIssuesLazyInput extends BaseLazyInput {
index aa5d5e98774a7c389f2c541b67b0afb2ed85492e..9d8d9430b3ff6bb7e13416de6e86613c82b5f8cb 100644 (file)
@@ -19,8 +19,8 @@
  */
 package org.sonar.ce.task.projectanalysis.issue;
 
-import com.google.common.base.Optional;
 import java.util.Date;
+import java.util.Optional;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.core.issue.DefaultIssue;
 import org.sonar.core.issue.IssueChangeContext;
index 63ae6cd23e6ad5dc3da68f640d55306a9e153584..b9c1eaef1ee88b346f1143c395fefd7a00a01cdd 100644 (file)
 package org.sonar.ce.task.projectanalysis.issue;
 
 import org.sonar.ce.task.projectanalysis.component.Component;
+import java.util.Optional;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.filemove.MovedFilesRepository;
 
-import com.google.common.base.Optional;
-
 public class RemoveProcessedComponentsVisitor extends IssueVisitor {
   private final ComponentsWithUnprocessedIssues componentsWithUnprocessedIssues;
   private final MovedFilesRepository movedFilesRepository;
index 903ef07513e5b9692c8aa5b5140a79a753161270..9e8054f76e408f6f35baf7a221bc2ca1649f316b 100644 (file)
@@ -63,7 +63,7 @@ public class TrackerBaseInputFactory extends BaseInputFactory {
       // Folders have no issues
       return new EmptyTrackerBaseLazyInput(dbClient, component);
     }
-    return new FileTrackerBaseLazyInput(dbClient, component, movedFilesRepository.getOriginalFile(component).orNull());
+    return new FileTrackerBaseLazyInput(dbClient, component, movedFilesRepository.getOriginalFile(component).orElse(null));
   }
 
   private class FileTrackerBaseLazyInput extends BaseLazyInput {
index 9c8aefa912c38ac52da253dbc62a331487b55b99..92d0d9b75a18fd0b49b0ddfbf98a6846f67be7a1 100644 (file)
@@ -26,6 +26,7 @@ import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
 import org.sonar.ce.task.projectanalysis.analysis.Branch;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.filemove.MovedFilesRepository;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.source.FileSourceDto;
@@ -34,11 +35,14 @@ public class ScmInfoDbLoader {
   private static final Logger LOGGER = Loggers.get(ScmInfoDbLoader.class);
 
   private final AnalysisMetadataHolder analysisMetadataHolder;
+  private final MovedFilesRepository movedFilesRepository;
   private final DbClient dbClient;
   private final MergeAndTargetBranchComponentUuids mergeBranchComponentUuid;
 
-  public ScmInfoDbLoader(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient, MergeAndTargetBranchComponentUuids mergeBranchComponentUuid) {
+  public ScmInfoDbLoader(AnalysisMetadataHolder analysisMetadataHolder, MovedFilesRepository movedFilesRepository, DbClient dbClient,
+    MergeAndTargetBranchComponentUuids mergeBranchComponentUuid) {
     this.analysisMetadataHolder = analysisMetadataHolder;
+    this.movedFilesRepository = movedFilesRepository;
     this.dbClient = dbClient;
     this.mergeBranchComponentUuid = mergeBranchComponentUuid;
   }
@@ -61,6 +65,10 @@ public class ScmInfoDbLoader {
 
   private Optional<String> getFileUUid(Component file) {
     if (!analysisMetadataHolder.isFirstAnalysis() && !analysisMetadataHolder.isSLBorPR()) {
+      Optional<MovedFilesRepository.OriginalFile> originalFile = movedFilesRepository.getOriginalFile(file);
+      if (originalFile.isPresent()) {
+        return originalFile.map(MovedFilesRepository.OriginalFile::getUuid);
+      }
       return Optional.of(file.getUuid());
     }
 
index f139d37e3d66072c897b34386d8a7a61d8ed3e9d..a0cf712fbe0ee3ffb40d89ffe606600db351ff63 100644 (file)
@@ -21,11 +21,11 @@ package org.sonar.ce.task.projectanalysis.source;
 
 import java.util.HashMap;
 import java.util.Map;
+import javax.annotation.CheckForNull;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.source.LineHashVersion;
-import org.sonar.ce.task.projectanalysis.component.Component;
 
 public class DbLineHashVersion {
   private final Map<Component, LineHashVersion> lineHashVersionPerComponent = new HashMap<>();
@@ -36,7 +36,7 @@ public class DbLineHashVersion {
   }
 
   /**
-   * Reads from DB the version of line hashes for a component and returns if it was generated taking into account the ranges of significant code.
+   * Reads from DB the version of line hashes for a component and returns whether it was generated taking into account the ranges of significant code.
    * The response is cached.
    * Returns false if the component is not in the DB.
    */
@@ -44,6 +44,16 @@ public class DbLineHashVersion {
     return lineHashVersionPerComponent.computeIfAbsent(component, this::compute) == LineHashVersion.WITH_SIGNIFICANT_CODE;
   }
 
+  /**
+   * Reads from DB the version of line hashes for a component and returns whether it was generated taking into account the ranges of significant code.
+   * The response is cached.
+   * Returns false if the component is not in the DB.
+   */
+  public boolean hasLineHashesWithoutSignificantCode(Component component) {
+    return lineHashVersionPerComponent.computeIfAbsent(component, this::compute) == LineHashVersion.WITHOUT_SIGNIFICANT_CODE;
+  }
+
+  @CheckForNull
   private LineHashVersion compute(Component component) {
     try (DbSession session = dbClient.openSession(false)) {
       return dbClient.fileSourceDao().selectLineHashesVersion(session, component.getUuid());
index 4e446cf7c524ca67935cb659a6006446f96b7532..a1e59148a139577042754e38eb94939b38b1c9e7 100644 (file)
@@ -113,7 +113,6 @@ public class PersistFileSourcesStep implements ComputationStep {
       Changeset latestChangeWithRevision = fileSourceData.getLatestChangeWithRevision();
       int lineHashesVersion = sourceLinesHash.getLineHashesVersion(file);
       FileSourceDto previousDto = previousFileSourcesByUuid.get(file.getUuid());
-
       if (previousDto == null) {
         FileSourceDto dto = new FileSourceDto()
           .setProjectUuid(projectUuid)
index de161a095189d49891dac84ef12a4c2dd8192f68..3d9502bf6e7db659d64b3363b80446569085514a 100644 (file)
@@ -21,9 +21,11 @@ package org.sonar.ce.task.projectanalysis.source;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.filemove.MovedFilesRepository;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.source.FileSourceDao;
@@ -34,14 +36,16 @@ public class SourceLinesDiffImpl implements SourceLinesDiff {
   private final FileSourceDao fileSourceDao;
   private final SourceLinesHashRepository sourceLinesHash;
   private final MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids;
+  private final MovedFilesRepository movedFilesRepository;
   private final AnalysisMetadataHolder analysisMetadataHolder;
 
   public SourceLinesDiffImpl(DbClient dbClient, FileSourceDao fileSourceDao, SourceLinesHashRepository sourceLinesHash,
-    MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids, AnalysisMetadataHolder analysisMetadataHolder) {
+      MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids, MovedFilesRepository movedFilesRepository, AnalysisMetadataHolder analysisMetadataHolder) {
     this.dbClient = dbClient;
     this.fileSourceDao = fileSourceDao;
     this.sourceLinesHash = sourceLinesHash;
     this.mergeAndTargetBranchComponentUuids = mergeAndTargetBranchComponentUuids;
+    this.movedFilesRepository = movedFilesRepository;
     this.analysisMetadataHolder = analysisMetadataHolder;
   }
 
@@ -62,7 +66,8 @@ public class SourceLinesDiffImpl implements SourceLinesDiff {
           uuid = mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(component.getDbKey());
         }
       } else {
-        uuid = component.getUuid();
+        Optional<MovedFilesRepository.OriginalFile> originalFile = movedFilesRepository.getOriginalFile(component);
+        uuid = originalFile.map(MovedFilesRepository.OriginalFile::getUuid).orElse(component.getUuid());
       }
 
       if (uuid == null) {
index a7afa6cd60f691d3893d5d40bb744c73c2341bfb..894a6c0f1ad52ad428c70a8355bd61fd9733a1e8 100644 (file)
@@ -61,7 +61,7 @@ public class SourceLinesHashRepositoryImpl implements SourceLinesHashRepository
     boolean cacheHit = cache.contains(component);
 
     // check if line hashes are cached and if we can use it
-    if (cacheHit && dbLineHashesVersion.hasLineHashesWithSignificantCode(component)) {
+    if (cacheHit && !dbLineHashesVersion.hasLineHashesWithoutSignificantCode(component)) {
       return new CachedLineHashesComputer(cache.get(component));
     }
 
@@ -75,10 +75,11 @@ public class SourceLinesHashRepositoryImpl implements SourceLinesHashRepository
   }
 
   private List<String> createLineHashesMatchingDBVersion(Component component) {
-    if (!dbLineHashesVersion.hasLineHashesWithSignificantCode(component)) {
+    if (dbLineHashesVersion.hasLineHashesWithoutSignificantCode(component)) {
       return createLineHashes(component, Optional.empty());
     }
 
+    // if the file is not in the DB, this will be used too
     Optional<LineRange[]> significantCodePerLine = significantCodeRepository.getRangesPerLine(component);
     return createLineHashes(component, significantCodePerLine);
   }
index 20384237dce2e2f3da071974d0b60b0b73f8102d..418f4a0e083ce5b52173a7df4510dccbfac392f6 100644 (file)
@@ -28,7 +28,6 @@ import org.sonar.ce.task.projectanalysis.component.ViewsComponent;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
-import static org.assertj.guava.api.Assertions.assertThat;
 import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;
 
 public class MutableMovedFilesRepositoryImplTest {
@@ -113,9 +112,9 @@ public class MutableMovedFilesRepositoryImplTest {
 
   @Test
   public void getOriginalFile_returns_absent_for_any_component_type_when_empty() {
-    assertThat(underTest.getOriginalFile(SOME_FILE)).isAbsent();
+    assertThat(underTest.getOriginalFile(SOME_FILE)).isEmpty();
     for (Component component : COMPONENTS_EXCEPT_FILE) {
-      assertThat(underTest.getOriginalFile(component)).isAbsent();
+      assertThat(underTest.getOriginalFile(component)).isEmpty();
     }
   }
 
@@ -124,7 +123,7 @@ public class MutableMovedFilesRepositoryImplTest {
     underTest.setOriginalFile(SOME_FILE, SOME_ORIGINAL_FILE);
 
     for (Component component : COMPONENTS_EXCEPT_FILE) {
-      assertThat(underTest.getOriginalFile(component)).isAbsent();
+      assertThat(underTest.getOriginalFile(component)).isEmpty();
     }
     assertThat(underTest.getOriginalFile(SOME_FILE)).contains(SOME_ORIGINAL_FILE);
   }
index 2b193b285ec803f74f7fbe5bb131554b36125ba6..510234809f584c6532ce27639fba00d2c6ba31fd 100644 (file)
@@ -19,8 +19,8 @@
  */
 package org.sonar.ce.task.projectanalysis.filemove;
 
-import com.google.common.base.Optional;
 import java.util.HashSet;
+import java.util.Optional;
 import java.util.Set;
 import javax.annotation.CheckForNull;
 import org.junit.rules.ExternalResource;
index 83a8f22b3fa9f02351aba69cd9623d4257a98e87..bc71cd1e4211404e1f3c9e2189ce1d78e53dcb01 100644 (file)
@@ -19,9 +19,9 @@
  */
 package org.sonar.ce.task.projectanalysis.issue;
 
-import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
 import java.util.List;
+import java.util.Optional;
 import org.junit.Test;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.component.ReportComponent;
@@ -47,7 +47,7 @@ public class ClosedIssuesInputFactoryTest {
   public void underTest_returns_inputFactory_loading_closed_issues_only_when_getIssues_is_called() {
     String componentUuid = randomAlphanumeric(12);
     ReportComponent component = ReportComponent.builder(Component.Type.FILE, 1).setUuid(componentUuid).build();
-    when(movedFilesRepository.getOriginalFile(component)).thenReturn(Optional.absent());
+    when(movedFilesRepository.getOriginalFile(component)).thenReturn(Optional.empty());
 
     Input<DefaultIssue> input = underTest.create(component);
 
@@ -81,7 +81,7 @@ public class ClosedIssuesInputFactoryTest {
   public void underTest_returns_inputFactory_which_caches_loaded_issues() {
     String componentUuid = randomAlphanumeric(12);
     ReportComponent component = ReportComponent.builder(Component.Type.FILE, 1).setUuid(componentUuid).build();
-    when(movedFilesRepository.getOriginalFile(component)).thenReturn(Optional.absent());
+    when(movedFilesRepository.getOriginalFile(component)).thenReturn(Optional.empty());
 
     Input<DefaultIssue> input = underTest.create(component);
 
index 4c4ba86943e99ec340c77642499bd192974e293d..b739226e67d67e038d4aa1ded9bf6f1fa4228df0 100644 (file)
@@ -19,9 +19,9 @@
  */
 package org.sonar.ce.task.projectanalysis.issue;
 
-import com.google.common.base.Optional;
 import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -139,7 +139,7 @@ public class IntegrateIssuesVisitorTest {
     IssueVisitors issueVisitors = new IssueVisitors(new IssueVisitor[] {issueVisitor});
 
     defaultIssueCaptor = ArgumentCaptor.forClass(DefaultIssue.class);
-    when(movedFilesRepository.getOriginalFile(any(Component.class))).thenReturn(Optional.absent());
+    when(movedFilesRepository.getOriginalFile(any(Component.class))).thenReturn(Optional.empty());
 
     DbClient dbClient = dbTester.getDbClient();
     TrackerRawInputFactory rawInputFactory = new TrackerRawInputFactory(treeRootHolder, reportReader, sourceLinesHash, new CommonRuleEngineImpl(),
index 386bf4a223158a3eaa88ff32c2fb544ea88408a4..a69a4e9c72048008e533e8c045fb0ef6b6ad85c1 100644 (file)
@@ -19,8 +19,8 @@
  */
 package org.sonar.ce.task.projectanalysis.issue;
 
-import com.google.common.base.Optional;
 import java.util.Date;
+import java.util.Optional;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -63,7 +63,7 @@ public class MovedIssueVisitorTest {
   public void setUp() throws Exception {
     analysisMetadataHolder.setAnalysisDate(ANALYSIS_DATE);
     when(movedFilesRepository.getOriginalFile(any(Component.class)))
-      .thenReturn(Optional.absent());
+      .thenReturn(Optional.empty());
   }
 
   @Test
index 10040bc8762be3d91c8776ccb490f4d0ea2eb271..e963520ea6d37b2f7370ad622719493b95266a3e 100644 (file)
@@ -19,7 +19,7 @@
  */
 package org.sonar.ce.task.projectanalysis.issue;
 
-import com.google.common.base.Optional;
+import java.util.Optional;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.ce.task.projectanalysis.component.Component;
@@ -46,7 +46,7 @@ public class RemoveProcessedComponentsVisitorTest {
 
   @Test
   public void remove_processed_files() {
-    when(movedFilesRepository.getOriginalFile(any(Component.class))).thenReturn(Optional.absent());
+    when(movedFilesRepository.getOriginalFile(any(Component.class))).thenReturn(Optional.empty());
     underTest.afterComponent(component);
 
     verify(movedFilesRepository).getOriginalFile(component);
index f9562921b332fa1e085bea3a071bfee2f112d6ee..c9f1f7077d90eca3724b25c9c3124e675677d694 100644 (file)
@@ -19,7 +19,7 @@
  */
 package org.sonar.ce.task.projectanalysis.issue;
 
-import com.google.common.base.Optional;
+import java.util.Optional;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
@@ -65,7 +65,7 @@ public class TrackerBaseInputFactoryTest {
     when(dbClient.openSession(false)).thenReturn(dbSession);
     when(dbClient.fileSourceDao()).thenReturn(fileSourceDao);
     when(movedFilesRepository.getOriginalFile(any(Component.class)))
-      .thenReturn(Optional.absent());
+      .thenReturn(Optional.empty());
   }
 
   @Test
index 8a47495bbdbd0d97cb7100a9bf3d01dd17ef7b9f..8133b22881aca027c2b4fdc5e4da57a86a485621 100644 (file)
@@ -34,6 +34,7 @@ import org.sonar.ce.task.projectanalysis.analysis.Branch;
 import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.filemove.MutableMovedFilesRepositoryRule;
 import org.sonar.core.hash.SourceHashComputer;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.BranchType;
@@ -67,11 +68,13 @@ public class ScmInfoDbLoaderTest {
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
+  @Rule
+  public MutableMovedFilesRepositoryRule movedFiles = new MutableMovedFilesRepositoryRule();
 
   private Branch branch = mock(Branch.class);
   private MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids = mock(MergeAndTargetBranchComponentUuids.class);
 
-  private ScmInfoDbLoader underTest = new ScmInfoDbLoader(analysisMetadataHolder, dbTester.getDbClient(), mergeAndTargetBranchComponentUuids);
+  private ScmInfoDbLoader underTest = new ScmInfoDbLoader(analysisMetadataHolder, movedFiles, dbTester.getDbClient(), mergeAndTargetBranchComponentUuids);
 
   @Test
   public void returns_ScmInfo_from_DB() {
index 28e2a8f21f43ae4bfba255e6122469278cb53e8b..a14d836c845b072a8bf8fafbf1c3e094404f8c20 100644 (file)
@@ -22,10 +22,12 @@ package org.sonar.ce.task.projectanalysis.source;
 import java.util.Arrays;
 import javax.annotation.Nullable;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
 import org.sonar.ce.task.projectanalysis.component.Component;
 import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids;
+import org.sonar.ce.task.projectanalysis.filemove.MutableMovedFilesRepositoryRule;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDao;
@@ -45,10 +47,12 @@ public class SourceLinesDiffImplTest {
   private FileSourceDao fileSourceDao = mock(FileSourceDao.class);
   private SourceLinesHashRepository sourceLinesHash = mock(SourceLinesHashRepository.class);
   private AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class);
+  @Rule
+  public MutableMovedFilesRepositoryRule movedFiles = new MutableMovedFilesRepositoryRule();
   private MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids = mock(MergeAndTargetBranchComponentUuids.class);
 
   private SourceLinesDiffImpl underTest = new SourceLinesDiffImpl(dbClient, fileSourceDao, sourceLinesHash,
-    mergeAndTargetBranchComponentUuids, analysisMetadataHolder);
+    mergeAndTargetBranchComponentUuids, movedFiles, analysisMetadataHolder);
 
   private static final int FILE_REF = 1;
 
index 67bce16c807c87e08dd947da1f41c8ab482911ba..a24df78dff58e7718353a208bd3082e6dd1fec76 100644 (file)
@@ -88,24 +88,24 @@ public class SourceLinesHashRepositoryImplTest {
 
   @Test
   public void should_create_hash_without_significant_code_if_db_has_no_significant_code() {
-    when(dbLineHashVersion.hasLineHashesWithSignificantCode(file)).thenReturn(false);
+    when(dbLineHashVersion.hasLineHashesWithoutSignificantCode(file)).thenReturn(true);
     List<String> lineHashes = underTest.getLineHashesMatchingDBVersion(file);
 
     assertLineHashes(lineHashes, "line1", "line2", "line3");
-    verify(dbLineHashVersion).hasLineHashesWithSignificantCode(file);
+    verify(dbLineHashVersion).hasLineHashesWithoutSignificantCode(file);
     verifyNoMoreInteractions(dbLineHashVersion);
     verifyZeroInteractions(significantCodeRepository);
   }
 
   @Test
   public void should_create_hash_without_significant_code_if_report_has_no_significant_code() {
-    when(dbLineHashVersion.hasLineHashesWithSignificantCode(file)).thenReturn(true);
+    when(dbLineHashVersion.hasLineHashesWithoutSignificantCode(file)).thenReturn(false);
     when(significantCodeRepository.getRangesPerLine(file)).thenReturn(Optional.empty());
 
     List<String> lineHashes = underTest.getLineHashesMatchingDBVersion(file);
 
     assertLineHashes(lineHashes, "line1", "line2", "line3");
-    verify(dbLineHashVersion).hasLineHashesWithSignificantCode(file);
+    verify(dbLineHashVersion).hasLineHashesWithoutSignificantCode(file);
     verifyNoMoreInteractions(dbLineHashVersion);
     verify(significantCodeRepository).getRangesPerLine(file);
     verifyNoMoreInteractions(significantCodeRepository);
@@ -121,7 +121,7 @@ public class SourceLinesHashRepositoryImplTest {
     List<String> lineHashes = underTest.getLineHashesMatchingDBVersion(file);
 
     assertLineHashes(lineHashes, "l", "", "ine3");
-    verify(dbLineHashVersion).hasLineHashesWithSignificantCode(file);
+    verify(dbLineHashVersion).hasLineHashesWithoutSignificantCode(file);
     verifyNoMoreInteractions(dbLineHashVersion);
     verify(significantCodeRepository).getRangesPerLine(file);
     verifyNoMoreInteractions(significantCodeRepository);
@@ -154,7 +154,7 @@ public class SourceLinesHashRepositoryImplTest {
     LineRange[] lineRanges = {new LineRange(0, 1), null, new LineRange(1, 5)};
     sourceLinesHashCache.computeIfAbsent(file, c -> lineHashes);
 
-    when(dbLineHashVersion.hasLineHashesWithSignificantCode(file)).thenReturn(true);
+    when(dbLineHashVersion.hasLineHashesWithoutSignificantCode(file)).thenReturn(false);
     when(significantCodeRepository.getRangesPerLine(file)).thenReturn(Optional.of(lineRanges));
 
     LineHashesComputer hashesComputer = underTest.getLineHashesComputerToPersist(file);
@@ -168,7 +168,7 @@ public class SourceLinesHashRepositoryImplTest {
     List<String> lineHashes = Lists.newArrayList("line1", "line2", "line3");
     sourceLinesHashCache.computeIfAbsent(file, c -> lineHashes);
 
-    when(dbLineHashVersion.hasLineHashesWithSignificantCode(file)).thenReturn(false);
+    when(dbLineHashVersion.hasLineHashesWithoutSignificantCode(file)).thenReturn(true);
     when(significantCodeRepository.getRangesPerLine(file)).thenReturn(Optional.empty());
 
     LineHashesComputer hashesComputer = underTest.getLineHashesComputerToPersist(file);
@@ -185,7 +185,7 @@ public class SourceLinesHashRepositoryImplTest {
     sourceLinesHashCache.computeIfAbsent(file, c -> lineHashes);
 
     // DB has line hashes without significant code and significant code is available in the report, so we need to generate new line hashes
-    when(dbLineHashVersion.hasLineHashesWithSignificantCode(file)).thenReturn(false);
+    when(dbLineHashVersion.hasLineHashesWithoutSignificantCode(file)).thenReturn(true);
     when(significantCodeRepository.getRangesPerLine(file)).thenReturn(Optional.of(lineRanges));
 
     LineHashesComputer hashesComputer = underTest.getLineHashesComputerToPersist(file);
index 1085b2c59e90c63618080bab36812be17d6ff1a5..a957e79d25788c87073bf3f1efe96a896cd46dd8 100644 (file)
@@ -50,7 +50,7 @@ public class FileSourceDao implements Dao {
   @CheckForNull
   public LineHashVersion selectLineHashesVersion(DbSession dbSession, String fileUuid) {
     Integer version = mapper(dbSession).selectLineHashesVersion(fileUuid);
-    return version == null ? LineHashVersion.WITHOUT_SIGNIFICANT_CODE : LineHashVersion.valueOf(version);
+    return version == null ? null : LineHashVersion.valueOf(version);
   }
 
   @CheckForNull
@@ -82,8 +82,8 @@ public class FileSourceDao implements Dao {
    * uuids in no specific order with 'SOURCE' source and a non null path.
    */
   public void scrollLineHashes(DbSession dbSession, Collection<String> fileUUids, ResultHandler<LineHashesWithUuidDto> rowHandler) {
-    for (List<String> partition : toUniqueAndSortedPartitions(fileUUids)) {
-      mapper(dbSession).scrollLineHashes(partition, rowHandler);
+    for (List<String> fileUuidsPartition : toUniqueAndSortedPartitions(fileUUids)) {
+      mapper(dbSession).scrollLineHashes(fileUuidsPartition, rowHandler);
     }
   }
 
index d875bf428075dc4779129f28e0e4333b4a43dbab..88fc7236ae4f8a35eda0b57ad617c95ca12c7037 100644 (file)
@@ -1087,13 +1087,6 @@ public class RegisterRulesTest {
     repo.done();
   }
 
-  private void verifyIndicesMarkedAsInitialized() {
-    verify(metadataIndex).setInitialized(RuleIndexDefinition.TYPE_RULE, true);
-    verify(metadataIndex).setInitialized(RuleIndexDefinition.TYPE_RULE_EXTENSION, true);
-    verify(metadataIndex).setInitialized(RuleIndexDefinition.TYPE_ACTIVE_RULE, true);
-    reset(metadataIndex);
-  }
-
   private RuleParamDto getParam(List<RuleParamDto> params, String key) {
     for (RuleParamDto param : params) {
       if (param.getName().equals(key)) {