1 | package org.apache.maven.continuum.web.action; |
2 | |
3 | /* |
4 | * Licensed to the Apache Software Foundation (ASF) under one |
5 | * or more contributor license agreements. See the NOTICE file |
6 | * distributed with this work for additional information |
7 | * regarding copyright ownership. The ASF licenses this file |
8 | * to you under the Apache License, Version 2.0 (the |
9 | * "License"); you may not use this file except in compliance |
10 | * with the License. You may obtain a copy of the License at |
11 | * |
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
13 | * |
14 | * Unless required by applicable law or agreed to in writing, |
15 | * software distributed under the License is distributed on an |
16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
17 | * KIND, either express or implied. See the License for the |
18 | * specific language governing permissions and limitations |
19 | * under the License. |
20 | */ |
21 | |
22 | import java.io.File; |
23 | import java.io.IOException; |
24 | import java.io.InputStream; |
25 | import java.util.List; |
26 | import java.util.Map; |
27 | |
28 | import org.apache.commons.io.IOUtils; |
29 | import org.apache.commons.lang.StringEscapeUtils; |
30 | import org.apache.continuum.builder.distributed.manager.DistributedBuildManager; |
31 | import org.apache.continuum.builder.utils.ContinuumBuildConstant; |
32 | import org.apache.continuum.buildmanager.BuildManagerException; |
33 | import org.apache.continuum.web.util.AuditLog; |
34 | import org.apache.continuum.web.util.AuditLogConstants; |
35 | import org.apache.maven.continuum.ContinuumException; |
36 | import org.apache.maven.continuum.configuration.ConfigurationException; |
37 | import org.apache.maven.continuum.configuration.ConfigurationService; |
38 | import org.apache.maven.continuum.model.project.BuildResult; |
39 | import org.apache.maven.continuum.model.project.Project; |
40 | import org.apache.maven.continuum.model.scm.ChangeSet; |
41 | import org.apache.maven.continuum.project.ContinuumProjectState; |
42 | import org.apache.maven.continuum.web.exception.AuthorizationRequiredException; |
43 | import org.apache.maven.continuum.web.util.StateGenerator; |
44 | import org.apache.struts2.ServletActionContext; |
45 | import org.codehaus.plexus.util.FileUtils; |
46 | import org.codehaus.plexus.util.StringUtils; |
47 | |
48 | |
49 | /** |
50 | * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a> |
51 | * @version $Id: BuildResultAction.java 897111 2010-01-08 06:28:43Z ctan $ |
52 | * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="buildResult" |
53 | */ |
54 | public class BuildResultAction |
55 | extends AbstractBuildAction |
56 | { |
57 | /** |
58 | * @plexus.requirement |
59 | */ |
60 | private DistributedBuildManager distributedBuildManager; |
61 | |
62 | private Project project; |
63 | |
64 | private BuildResult buildResult; |
65 | |
66 | private int buildId; |
67 | |
68 | private List<ChangeSet> changeSet; |
69 | |
70 | private boolean hasSurefireResults; |
71 | |
72 | private String buildOutput; |
73 | |
74 | private String state; |
75 | |
76 | private String projectGroupName = ""; |
77 | |
78 | private int projectGroupId; |
79 | |
80 | public String execute() |
81 | throws ContinuumException, ConfigurationException, IOException, BuildManagerException |
82 | { |
83 | try |
84 | { |
85 | checkViewProjectGroupAuthorization( getProjectGroupName() ); |
86 | } |
87 | catch ( AuthorizationRequiredException e ) |
88 | { |
89 | return REQUIRES_AUTHORIZATION; |
90 | } |
91 | |
92 | //todo get this working for other types of test case rendering other then just surefire |
93 | // check if there are surefire results to display |
94 | project = getContinuum().getProject( getProjectId() ); |
95 | |
96 | ConfigurationService configuration = getContinuum().getConfiguration(); |
97 | |
98 | // view build result of the current build from the distributed build agent |
99 | if ( configuration.isDistributedBuildEnabled() && |
100 | project.getState() == ContinuumProjectState.BUILDING && getBuildId() == 0 ) |
101 | { |
102 | // if the project is currently building in distributed build agent, the build result will be stored in the database after the build is finished. |
103 | // it's safe to assume that the build result will be null at this point |
104 | Map<String, Object> map = distributedBuildManager.getBuildResult( project.getId() ); |
105 | |
106 | if ( map == null ) |
107 | { |
108 | projectGroupId = project.getProjectGroup().getId(); |
109 | |
110 | return ERROR; |
111 | } |
112 | |
113 | if ( map.size() > 0 ) |
114 | { |
115 | buildResult = ContinuumBuildConstant.getBuildResult( map, null ); |
116 | |
117 | buildOutput = ContinuumBuildConstant.getBuildOutput( map ); |
118 | |
119 | if ( ServletActionContext.getRequest() != null ) |
120 | { |
121 | state = |
122 | StateGenerator.generate( buildResult.getState(), ServletActionContext.getRequest().getContextPath() ); |
123 | } |
124 | } |
125 | changeSet = null; |
126 | |
127 | hasSurefireResults = false; |
128 | |
129 | this.setCanDelete( false ); |
130 | } |
131 | else |
132 | { |
133 | buildResult = getContinuum().getBuildResult( getBuildId() ); |
134 | |
135 | // directory contains files ? |
136 | File surefireReportsDirectory = |
137 | configuration.getTestReportsDirectory( buildId, getProjectId() ); |
138 | File[] files = surefireReportsDirectory.listFiles(); |
139 | hasSurefireResults = files != null && files.length > 0; |
140 | changeSet = getContinuum().getChangesSinceLastSuccess( getProjectId(), getBuildId() ); |
141 | |
142 | buildOutput = getBuildOutputText(); |
143 | |
144 | if ( ServletActionContext.getRequest() != null ) |
145 | { |
146 | state = |
147 | StateGenerator.generate( buildResult.getState(), ServletActionContext.getRequest().getContextPath() ); |
148 | } |
149 | |
150 | this.setCanDelete( this.canRemoveBuildResult( buildResult ) ); |
151 | } |
152 | |
153 | return SUCCESS; |
154 | } |
155 | |
156 | public String remove() |
157 | throws ContinuumException |
158 | { |
159 | try |
160 | { |
161 | checkModifyProjectGroupAuthorization( getProjectGroupName() ); |
162 | } |
163 | catch ( AuthorizationRequiredException e ) |
164 | { |
165 | return REQUIRES_AUTHORIZATION; |
166 | } |
167 | if ( this.isConfirmed() ) |
168 | { |
169 | try |
170 | { |
171 | if ( canRemoveBuildResult( getContinuum().getBuildResult( buildId ) ) ) |
172 | { |
173 | getContinuum().removeBuildResult( buildId ); |
174 | } |
175 | else |
176 | { |
177 | addActionError( getText( "buildResult.cannot.delete" ) ); |
178 | } |
179 | } |
180 | catch ( ContinuumException e ) |
181 | { |
182 | addActionError( getText( "buildResult.delete.error", "Unable to delete build result", |
183 | new Integer( buildId ).toString() ) ); |
184 | } |
185 | catch ( BuildManagerException e ) |
186 | { |
187 | throw new ContinuumException( e.getMessage(), e ); |
188 | } |
189 | |
190 | AuditLog event = new AuditLog( "Build Result id=" + buildId, AuditLogConstants.REMOVE_BUILD_RESULT ); |
191 | event.setCategory( AuditLogConstants.BUILD_RESULT ); |
192 | event.setCurrentUser( getPrincipal() ); |
193 | event.log(); |
194 | |
195 | return SUCCESS; |
196 | } |
197 | |
198 | return CONFIRM; |
199 | } |
200 | |
201 | |
202 | public String buildLogAsText() |
203 | throws ConfigurationException, IOException |
204 | { |
205 | buildOutput = getBuildOutputText(); |
206 | return SUCCESS; |
207 | } |
208 | |
209 | public InputStream getBuildOutputInputStream() |
210 | throws ConfigurationException, IOException |
211 | { |
212 | String outputText = getBuildOutputText(); |
213 | return outputText == null ? null : IOUtils.toInputStream( outputText ); |
214 | } |
215 | |
216 | private String getBuildOutputText() |
217 | throws ConfigurationException, IOException |
218 | { |
219 | ConfigurationService configuration = getContinuum().getConfiguration(); |
220 | File buildOutputFile = configuration.getBuildOutputFile( getBuildId(), getProjectId() ); |
221 | |
222 | if ( buildOutputFile.exists() ) |
223 | { |
224 | return StringEscapeUtils.escapeHtml( FileUtils.fileRead( buildOutputFile ) ); |
225 | } |
226 | return null; |
227 | } |
228 | |
229 | |
230 | public int getBuildId() |
231 | { |
232 | return buildId; |
233 | } |
234 | |
235 | public void setBuildId( int buildId ) |
236 | { |
237 | this.buildId = buildId; |
238 | } |
239 | |
240 | public Project getProject() |
241 | { |
242 | return project; |
243 | } |
244 | |
245 | public BuildResult getBuildResult() |
246 | { |
247 | return buildResult; |
248 | } |
249 | |
250 | public List<ChangeSet> getChangesSinceLastSuccess() |
251 | { |
252 | return changeSet; |
253 | } |
254 | |
255 | public boolean isHasSurefireResults() |
256 | { |
257 | return hasSurefireResults; |
258 | } |
259 | |
260 | public void setHasSurefireResults( boolean hasSurefireResults ) |
261 | { |
262 | this.hasSurefireResults = hasSurefireResults; |
263 | } |
264 | |
265 | public String getBuildOutput() |
266 | { |
267 | return buildOutput; |
268 | } |
269 | |
270 | public String getState() |
271 | { |
272 | return state; |
273 | } |
274 | |
275 | public String getProjectGroupName() |
276 | throws ContinuumException |
277 | { |
278 | if ( StringUtils.isEmpty( projectGroupName ) ) |
279 | { |
280 | projectGroupName = getContinuum().getProjectGroupByProjectId( getProjectId() ).getName(); |
281 | } |
282 | |
283 | return projectGroupName; |
284 | } |
285 | |
286 | public int getProjectGroupId() |
287 | { |
288 | return projectGroupId; |
289 | } |
290 | |
291 | // for testing |
292 | public void setDistributedBuildManager( DistributedBuildManager distributedBuildManager ) |
293 | { |
294 | this.distributedBuildManager = distributedBuildManager; |
295 | } |
296 | } |