3 * Copyright (C) 2009-2016 SonarSource SA
4 * mailto:contact AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.server.computation.task.projectanalysis.step;
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;
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;
45 * Populates the {@link PeriodHolder}
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
52 public class LoadPeriodsStep implements ComputationStep {
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;
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;
70 public void execute() {
71 new DepthTraversalTypeAwareCrawler(
72 new TypeAwareVisitorAdapter(reportMaxDepth(PROJECT).withViewsMaxDepth(VIEW), PRE_ORDER) {
74 public void visitProject(Component project) {
79 public void visitView(Component view) {
82 }).visit(treeRootHolder.getRoot());
85 public void execute(Component projectOrView) {
86 DbSession session = dbClient.openSession(false);
88 periodsHolder.setPeriod(buildPeriod(projectOrView, session));
90 dbClient.closeSession(session);
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()) {
102 boolean isReportType = projectOrView.getType().isReportType();
103 PeriodResolver periodResolver = new PeriodResolver(dbClient, session, projectDto.get().uuid(), analysisMetadataHolder.getAnalysisDate(),
104 isReportType ? projectOrView.getReportAttributes().getVersion() : null);
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) {
116 public String getDescription() {
117 return "Load differential periods";