]> source.dussan.org Git - sonarqube.git/blob
1fed2f087ceb0603045ce3958a8dc62155668adf
[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.api.posttask;
21
22 import com.google.common.base.Optional;
23 import java.util.Collection;
24 import java.util.Date;
25 import java.util.Map;
26 import java.util.Set;
27 import javax.annotation.CheckForNull;
28 import javax.annotation.Nullable;
29 import org.sonar.api.ce.posttask.CeTask;
30 import org.sonar.api.ce.posttask.PostProjectAnalysisTask;
31 import org.sonar.api.ce.posttask.Project;
32 import org.sonar.api.ce.posttask.QualityGate;
33 import org.sonar.api.ce.posttask.ScannerContext;
34 import org.sonar.api.utils.System2;
35 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
36 import org.sonar.server.computation.task.projectanalysis.batch.BatchReportReader;
37 import org.sonar.server.computation.task.projectanalysis.qualitygate.Condition;
38 import org.sonar.server.computation.task.projectanalysis.qualitygate.ConditionStatus;
39 import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGateHolder;
40 import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGateStatus;
41 import org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGateStatusHolder;
42 import org.sonar.server.computation.task.step.ComputationStepExecutor;
43
44 import static com.google.common.collect.FluentIterable.from;
45 import static java.lang.String.format;
46 import static java.util.Objects.requireNonNull;
47 import static org.sonar.api.ce.posttask.CeTask.Status.FAILED;
48 import static org.sonar.api.ce.posttask.CeTask.Status.SUCCESS;
49
50 /**
51  * Responsible for calling {@link PostProjectAnalysisTask} implementations (if any).
52  */
53 public class PostProjectAnalysisTasksExecutor implements ComputationStepExecutor.Listener {
54   private static final PostProjectAnalysisTask[] NO_POST_PROJECT_ANALYSIS_TASKS = new PostProjectAnalysisTask[0];
55
56   private final org.sonar.ce.queue.CeTask ceTask;
57   private final AnalysisMetadataHolder analysisMetadataHolder;
58   private final QualityGateHolder qualityGateHolder;
59   private final QualityGateStatusHolder qualityGateStatusHolder;
60   private final PostProjectAnalysisTask[] postProjectAnalysisTasks;
61   private final BatchReportReader reportReader;
62   private final System2 system2;
63
64   /**
65    * Constructor used by Pico when there is no {@link PostProjectAnalysisTask} in the container.
66    */
67   public PostProjectAnalysisTasksExecutor(org.sonar.ce.queue.CeTask ceTask,
68     AnalysisMetadataHolder analysisMetadataHolder,
69     QualityGateHolder qualityGateHolder, QualityGateStatusHolder qualityGateStatusHolder,
70     BatchReportReader reportReader, System2 system2) {
71     this(ceTask, analysisMetadataHolder, qualityGateHolder, qualityGateStatusHolder, reportReader, system2, null);
72   }
73
74   public PostProjectAnalysisTasksExecutor(org.sonar.ce.queue.CeTask ceTask,
75     AnalysisMetadataHolder analysisMetadataHolder,
76     QualityGateHolder qualityGateHolder, QualityGateStatusHolder qualityGateStatusHolder,
77     BatchReportReader reportReader, System2 system2,
78     @Nullable PostProjectAnalysisTask[] postProjectAnalysisTasks) {
79     this.analysisMetadataHolder = analysisMetadataHolder;
80     this.qualityGateHolder = qualityGateHolder;
81     this.qualityGateStatusHolder = qualityGateStatusHolder;
82     this.ceTask = ceTask;
83     this.reportReader = reportReader;
84     this.postProjectAnalysisTasks = postProjectAnalysisTasks == null ? NO_POST_PROJECT_ANALYSIS_TASKS : postProjectAnalysisTasks;
85     this.system2 = system2;
86   }
87
88   @Override
89   public void finished(boolean allStepsExecuted) {
90     if (postProjectAnalysisTasks.length == 0) {
91       return;
92     }
93
94     ProjectAnalysis projectAnalysis = createProjectAnalysis(allStepsExecuted ? SUCCESS : FAILED);
95     for (PostProjectAnalysisTask postProjectAnalysisTask : postProjectAnalysisTasks) {
96       postProjectAnalysisTask.finished(projectAnalysis);
97     }
98   }
99
100   private ProjectAnalysis createProjectAnalysis(CeTask.Status status) {
101     Long analysisDate = getAnalysisDate();
102     return new ProjectAnalysis(
103       new CeTaskImpl(this.ceTask.getUuid(), status),
104       createProject(this.ceTask),
105       analysisDate,
106       analysisDate == null ? system2.now() : analysisDate,
107       ScannerContextImpl.from(reportReader.readContextProperties()),
108       status == SUCCESS ? createQualityGate(this.qualityGateHolder) : null);
109   }
110
111   private static Project createProject(org.sonar.ce.queue.CeTask ceTask) {
112     return new ProjectImpl(
113       ceTask.getComponentUuid(),
114       ceTask.getComponentKey(),
115       ceTask.getComponentName());
116   }
117
118   @CheckForNull
119   private Long getAnalysisDate() {
120     if (this.analysisMetadataHolder.hasAnalysisDateBeenSet()) {
121       return this.analysisMetadataHolder.getAnalysisDate();
122     }
123     return null;
124   }
125
126   @CheckForNull
127   private QualityGateImpl createQualityGate(QualityGateHolder qualityGateHolder) {
128     Optional<org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGate> qualityGateOptional = qualityGateHolder.getQualityGate();
129     if (qualityGateOptional.isPresent()) {
130       org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGate qualityGate = qualityGateOptional.get();
131
132       return new QualityGateImpl(
133         String.valueOf(qualityGate.getId()),
134         qualityGate.getName(),
135         convert(qualityGateStatusHolder.getStatus()),
136         convert(qualityGate.getConditions(), qualityGateStatusHolder.getStatusPerConditions()));
137     }
138     return null;
139   }
140
141   private static QualityGate.Status convert(QualityGateStatus status) {
142     switch (status) {
143       case OK:
144         return QualityGate.Status.OK;
145       case WARN:
146         return QualityGate.Status.WARN;
147       case ERROR:
148         return QualityGate.Status.ERROR;
149       default:
150         throw new IllegalArgumentException(format(
151           "Unsupported value '%s' of QualityGateStatus can not be converted to QualityGate.Status",
152           status));
153     }
154   }
155
156   private static Collection<QualityGate.Condition> convert(Set<Condition> conditions, Map<Condition, ConditionStatus> statusPerConditions) {
157     return from(conditions)
158       .transform(new ConditionToCondition(statusPerConditions))
159       .toList();
160   }
161
162   private static class ProjectAnalysis implements PostProjectAnalysisTask.ProjectAnalysis {
163     private final CeTask ceTask;
164     private final Project project;
165     @CheckForNull
166     private final Long analysisDate;
167     private final long date;
168     private final ScannerContext scannerContext;
169     @CheckForNull
170     private final QualityGate qualityGate;
171
172     private ProjectAnalysis(CeTask ceTask, Project project,
173       @Nullable Long analysisDate, long date,
174       ScannerContext scannerContext, @Nullable QualityGate qualityGate) {
175       this.ceTask = requireNonNull(ceTask, "ceTask can not be null");
176       this.project = requireNonNull(project, "project can not be null");
177       this.analysisDate = analysisDate;
178       this.date = date;
179       this.scannerContext = requireNonNull(scannerContext, "scannerContext can not be null");
180       this.qualityGate = qualityGate;
181     }
182
183     @Override
184     public CeTask getCeTask() {
185       return ceTask;
186     }
187
188     @Override
189     public Project getProject() {
190       return project;
191     }
192
193     @Override
194     @CheckForNull
195     public QualityGate getQualityGate() {
196       return qualityGate;
197     }
198
199     @Override
200     public Date getDate() {
201       return new Date(date);
202     }
203
204     @Override
205     public java.util.Optional<Date> getAnalysisDate() {
206       if (analysisDate == null) {
207         return java.util.Optional.empty();
208       }
209       return java.util.Optional.of(new Date(analysisDate));
210     }
211
212     @Override
213     public ScannerContext getScannerContext() {
214       return scannerContext;
215     }
216
217     @Override
218     public String toString() {
219       return "ProjectAnalysis{" +
220         "ceTask=" + ceTask +
221         ", project=" + project +
222         ", analysisDate=" + analysisDate +
223         ", date=" + date +
224         ", scannerContext=" + scannerContext +
225         ", qualityGate=" + qualityGate +
226         '}';
227     }
228   }
229
230 }