]> source.dussan.org Git - sonarqube.git/blob
a36268bb8dbba976cb364e5b43e47de2964415c1
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2023 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.ce.task.projectanalysis.component;
21
22 import java.util.HashSet;
23 import java.util.Optional;
24 import java.util.Set;
25 import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
26 import org.sonar.ce.task.projectanalysis.source.SourceHashRepository;
27 import org.sonar.db.source.FileHashesDto;
28
29 import static com.google.common.base.Preconditions.checkState;
30 import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
31
32 public class FileStatusesImpl implements FileStatuses {
33   private final PreviousSourceHashRepository previousSourceHashRepository;
34   private final SourceHashRepository sourceHashRepository;
35   private final AnalysisMetadataHolder analysisMetadataHolder;
36   private final TreeRootHolder treeRootHolder;
37   private Set<String> fileUuidsMarkedAsUnchanged;
38
39   public FileStatusesImpl(AnalysisMetadataHolder analysisMetadataHolder, TreeRootHolder treeRootHolder, PreviousSourceHashRepository previousSourceHashRepository,
40     SourceHashRepository sourceHashRepository) {
41     this.analysisMetadataHolder = analysisMetadataHolder;
42     this.treeRootHolder = treeRootHolder;
43     this.previousSourceHashRepository = previousSourceHashRepository;
44     this.sourceHashRepository = sourceHashRepository;
45   }
46
47   public void initialize() {
48     fileUuidsMarkedAsUnchanged = new HashSet<>();
49     if (!analysisMetadataHolder.isPullRequest() && !analysisMetadataHolder.isFirstAnalysis()) {
50       new DepthTraversalTypeAwareCrawler(new Visitor()).visit(treeRootHolder.getRoot());
51     }
52   }
53
54   private class Visitor extends TypeAwareVisitorAdapter {
55     private boolean canTrustUnchangedFlags = true;
56
57     private Visitor() {
58       super(CrawlerDepthLimit.FILE, PRE_ORDER);
59     }
60
61     @Override
62     public void visitFile(Component file) {
63       if (file.getStatus() != Component.Status.SAME || !canTrustUnchangedFlags) {
64         return;
65       }
66
67       canTrustUnchangedFlags = hashEquals(file);
68       if (canTrustUnchangedFlags) {
69         if (file.getFileAttributes().isMarkedAsUnchanged()) {
70           fileUuidsMarkedAsUnchanged.add(file.getUuid());
71         }
72       } else {
73         fileUuidsMarkedAsUnchanged.clear();
74       }
75     }
76   }
77
78   @Override
79   public boolean isUnchanged(Component component) {
80     failIfNotInitialized();
81     return component.getStatus() == Component.Status.SAME && hashEquals(component);
82   }
83
84   @Override
85   public boolean isDataUnchanged(Component component) {
86     failIfNotInitialized();
87     return fileUuidsMarkedAsUnchanged.contains(component.getUuid());
88   }
89
90   private boolean hashEquals(Component component) {
91     Optional<String> dbHash = previousSourceHashRepository.getDbFile(component).map(FileHashesDto::getSrcHash);
92     return dbHash.map(hash -> hash.equals(sourceHashRepository.getRawSourceHash(component))).orElse(false);
93   }
94
95   private void failIfNotInitialized() {
96     checkState(fileUuidsMarkedAsUnchanged != null, "Not initialized");
97   }
98 }