]> source.dussan.org Git - sonarqube.git/blob
563bacd42097c93a2bc1b7c1c260bb959020c6b5
[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     return new ProjectAnalysis(
102       new CeTaskImpl(this.ceTask.getUuid(), status),
103       createProject(this.ceTask),
104       getAnalysisDate(),
105       ScannerContextImpl.from(reportReader.readContextProperties()),
106       status == SUCCESS ? createQualityGate(this.qualityGateHolder) : null);
107   }
108
109   private static Project createProject(org.sonar.ce.queue.CeTask ceTask) {
110     return new ProjectImpl(
111       ceTask.getComponentUuid(),
112       ceTask.getComponentKey(),
113       ceTask.getComponentName());
114   }
115
116   private long getAnalysisDate() {
117     if (this.analysisMetadataHolder.hasAnalysisDateBeenSet()) {
118       return this.analysisMetadataHolder.getAnalysisDate();
119     }
120     return system2.now();
121   }
122
123   @CheckForNull
124   private QualityGateImpl createQualityGate(QualityGateHolder qualityGateHolder) {
125     Optional<org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGate> qualityGateOptional = qualityGateHolder.getQualityGate();
126     if (qualityGateOptional.isPresent()) {
127       org.sonar.server.computation.task.projectanalysis.qualitygate.QualityGate qualityGate = qualityGateOptional.get();
128
129       return new QualityGateImpl(
130         String.valueOf(qualityGate.getId()),
131         qualityGate.getName(),
132         convert(qualityGateStatusHolder.getStatus()),
133         convert(qualityGate.getConditions(), qualityGateStatusHolder.getStatusPerConditions()));
134     }
135     return null;
136   }
137
138   private static QualityGate.Status convert(QualityGateStatus status) {
139     switch (status) {
140       case OK:
141         return QualityGate.Status.OK;
142       case WARN:
143         return QualityGate.Status.WARN;
144       case ERROR:
145         return QualityGate.Status.ERROR;
146       default:
147         throw new IllegalArgumentException(format(
148           "Unsupported value '%s' of QualityGateStatus can not be converted to QualityGate.Status",
149           status));
150     }
151   }
152
153   private static Collection<QualityGate.Condition> convert(Set<Condition> conditions, Map<Condition, ConditionStatus> statusPerConditions) {
154     return from(conditions)
155       .transform(new ConditionToCondition(statusPerConditions))
156       .toList();
157   }
158
159   private static class ProjectAnalysis implements PostProjectAnalysisTask.ProjectAnalysis {
160     private final CeTask ceTask;
161     private final Project project;
162     private final long date;
163     private final ScannerContext scannerContext;
164     @CheckForNull
165     private final QualityGate qualityGate;
166
167     private ProjectAnalysis(CeTask ceTask, Project project, long date,
168       ScannerContext scannerContext, @Nullable QualityGate qualityGate) {
169       this.ceTask = requireNonNull(ceTask, "ceTask can not be null");
170       this.project = requireNonNull(project, "project can not be null");
171       this.date = date;
172       this.scannerContext = requireNonNull(scannerContext, "scannerContext can not be null");
173       this.qualityGate = qualityGate;
174     }
175
176     @Override
177     public CeTask getCeTask() {
178       return ceTask;
179     }
180
181     @Override
182     public Project getProject() {
183       return project;
184     }
185
186     @Override
187     @CheckForNull
188     public QualityGate getQualityGate() {
189       return qualityGate;
190     }
191
192     @Override
193     public Date getDate() {
194       return new Date(date);
195     }
196
197     @Override
198     public ScannerContext getScannerContext() {
199       return scannerContext;
200     }
201
202     @Override
203     public String toString() {
204       return "ProjectAnalysis{" +
205         "ceTask=" + ceTask +
206         ", project=" + project +
207         ", date=" + date +
208         ", qualityGate=" + qualityGate +
209         '}';
210     }
211   }
212
213 }