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