View Javadoc

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 }