]> source.dussan.org Git - sonarqube.git/blob
f2623ead683b797d586e38cf074d7d35c647d1df
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2016 SonarSource SA
4  * mailto:contact 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.server.computation.task.projectanalysis.step;
21
22 import com.google.common.base.Optional;
23 import javax.annotation.CheckForNull;
24 import org.sonar.api.config.Settings;
25 import org.sonar.db.DbClient;
26 import org.sonar.db.DbSession;
27 import org.sonar.db.component.ComponentDto;
28 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
29 import org.sonar.server.computation.task.projectanalysis.component.Component;
30 import org.sonar.server.computation.task.projectanalysis.component.DepthTraversalTypeAwareCrawler;
31 import org.sonar.server.computation.task.projectanalysis.component.SettingsRepository;
32 import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder;
33 import org.sonar.server.computation.task.projectanalysis.component.TypeAwareVisitorAdapter;
34 import org.sonar.server.computation.task.projectanalysis.period.Period;
35 import org.sonar.server.computation.task.projectanalysis.period.PeriodHolder;
36 import org.sonar.server.computation.task.projectanalysis.period.PeriodHolderImpl;
37 import org.sonar.server.computation.task.step.ComputationStep;
38
39 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT;
40 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.VIEW;
41 import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
42 import static org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit.reportMaxDepth;
43
44 /**
45  * Populates the {@link PeriodHolder}
46  * <p/>
47  * Here is how these periods are computed :
48  * - Read the 5 period properties ${@link org.sonar.core.config.CorePropertyDefinitions#TIMEMACHINE_PERIOD_PREFIX}
49  * - Try to find the matching snapshots from the properties
50  * - If a snapshot is found, a new period is added to the repository
51  */
52 public class LoadPeriodsStep implements ComputationStep {
53
54   private final DbClient dbClient;
55   private final SettingsRepository settingsRepository;
56   private final TreeRootHolder treeRootHolder;
57   private final AnalysisMetadataHolder analysisMetadataHolder;
58   private final PeriodHolderImpl periodsHolder;
59
60   public LoadPeriodsStep(DbClient dbClient, SettingsRepository settingsRepository, TreeRootHolder treeRootHolder, AnalysisMetadataHolder analysisMetadataHolder,
61     PeriodHolderImpl periodsHolder) {
62     this.dbClient = dbClient;
63     this.settingsRepository = settingsRepository;
64     this.treeRootHolder = treeRootHolder;
65     this.analysisMetadataHolder = analysisMetadataHolder;
66     this.periodsHolder = periodsHolder;
67   }
68
69   @Override
70   public void execute() {
71     new DepthTraversalTypeAwareCrawler(
72       new TypeAwareVisitorAdapter(reportMaxDepth(PROJECT).withViewsMaxDepth(VIEW), PRE_ORDER) {
73         @Override
74         public void visitProject(Component project) {
75           execute(project);
76         }
77
78         @Override
79         public void visitView(Component view) {
80           execute(view);
81         }
82       }).visit(treeRootHolder.getRoot());
83   }
84
85   public void execute(Component projectOrView) {
86     DbSession session = dbClient.openSession(false);
87     try {
88       periodsHolder.setPeriod(buildPeriod(projectOrView, session));
89     } finally {
90       dbClient.closeSession(session);
91     }
92   }
93
94   @CheckForNull
95   private Period buildPeriod(Component projectOrView, DbSession session) {
96     Optional<ComponentDto> projectDto = dbClient.componentDao().selectByKey(session, projectOrView.getKey());
97     // No project on first analysis, no period
98     if (!projectDto.isPresent()) {
99       return null;
100     }
101
102     boolean isReportType = projectOrView.getType().isReportType();
103     PeriodResolver periodResolver = new PeriodResolver(dbClient, session, projectDto.get().uuid(), analysisMetadataHolder.getAnalysisDate(),
104       isReportType ? projectOrView.getReportAttributes().getVersion() : null);
105
106     Settings settings = settingsRepository.getSettings(projectOrView);
107     Period period = periodResolver.resolve(settings);
108     // SONAR-4700 Add a past snapshot only if it exists
109     if (period != null) {
110       return period;
111     }
112     return null;
113   }
114
115   @Override
116   public String getDescription() {
117     return "Load differential periods";
118   }
119 }