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