]> source.dussan.org Git - sonarqube.git/blob
21471cbf0d1c0a6bede360581e0a4be778746f03
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 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.api.utils.log.Logger;
26 import org.sonar.api.utils.log.Loggers;
27 import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
28 import org.sonar.ce.task.projectanalysis.source.SourceHashRepository;
29 import org.sonar.db.source.FileHashesDto;
30
31 import static com.google.common.base.Preconditions.checkState;
32 import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
33
34 public class FileStatusesImpl implements FileStatuses {
35   private static final Logger LOG = Loggers.get(FileStatusesImpl.class);
36
37   private final PreviousSourceHashRepository previousSourceHashRepository;
38   private final SourceHashRepository sourceHashRepository;
39   private final AnalysisMetadataHolder analysisMetadataHolder;
40   private final TreeRootHolder treeRootHolder;
41   private Set<String> fileUuidsMarkedAsUnchanged;
42   private int notMarkedAsUnchanged = 0;
43
44   public FileStatusesImpl(AnalysisMetadataHolder analysisMetadataHolder, TreeRootHolder treeRootHolder, PreviousSourceHashRepository previousSourceHashRepository,
45     SourceHashRepository sourceHashRepository) {
46     this.analysisMetadataHolder = analysisMetadataHolder;
47     this.treeRootHolder = treeRootHolder;
48     this.previousSourceHashRepository = previousSourceHashRepository;
49     this.sourceHashRepository = sourceHashRepository;
50   }
51
52   public void initialize() {
53     fileUuidsMarkedAsUnchanged = new HashSet<>();
54     if (!analysisMetadataHolder.isPullRequest() && !analysisMetadataHolder.isFirstAnalysis()) {
55       new DepthTraversalTypeAwareCrawler(new Visitor()).visit(treeRootHolder.getRoot());
56     }
57     LOG.warn("FILES MARKED AS UNCHANGED: " + fileUuidsMarkedAsUnchanged.size());
58     LOG.warn("FILES NOT MARKED AS UNCHANGED: " + notMarkedAsUnchanged);
59   }
60
61   private class Visitor extends TypeAwareVisitorAdapter {
62     private boolean canTrustUnchangedFlags = true;
63
64     private Visitor() {
65       super(CrawlerDepthLimit.FILE, PRE_ORDER);
66     }
67
68     @Override
69     public void visitFile(Component file) {
70       if (file.getStatus() != Component.Status.SAME || !canTrustUnchangedFlags) {
71         return;
72       }
73
74       canTrustUnchangedFlags = hashEquals(file);
75       if (canTrustUnchangedFlags) {
76         if (file.getFileAttributes().isMarkedAsUnchanged()) {
77           fileUuidsMarkedAsUnchanged.add(file.getUuid());
78         } else {
79           notMarkedAsUnchanged++;
80         }
81       } else {
82         LOG.error("FILE HAS DIFFERENT HASH: " + file.getName());
83         fileUuidsMarkedAsUnchanged.clear();
84       }
85     }
86   }
87
88   @Override
89   public boolean isUnchanged(Component component) {
90     failIfNotInitialized();
91     return component.getStatus() == Component.Status.SAME && hashEquals(component);
92   }
93
94   @Override
95   public boolean isDataUnchanged(Component component) {
96     failIfNotInitialized();
97     return fileUuidsMarkedAsUnchanged.contains(component.getUuid());
98   }
99
100   private boolean hashEquals(Component component) {
101     Optional<String> dbHash = previousSourceHashRepository.getDbFile(component).map(FileHashesDto::getSrcHash);
102     return dbHash.map(hash -> hash.equals(sourceHashRepository.getRawSourceHash(component))).orElse(false);
103   }
104
105   private void failIfNotInitialized() {
106     checkState(fileUuidsMarkedAsUnchanged != null, "Not initialized");
107   }
108 }