1 package org.apache.maven.continuum.core.action;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.util.Date;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.continuum.dao.BuildResultDao;
29 import org.apache.continuum.dao.ProjectDao;
30 import org.apache.continuum.scm.ContinuumScm;
31 import org.apache.continuum.scm.ContinuumScmConfiguration;
32 import org.apache.continuum.utils.ContinuumUtils;
33 import org.apache.maven.continuum.model.project.BuildDefinition;
34 import org.apache.maven.continuum.model.project.BuildResult;
35 import org.apache.maven.continuum.model.project.Project;
36 import org.apache.maven.continuum.model.scm.ChangeFile;
37 import org.apache.maven.continuum.model.scm.ChangeSet;
38 import org.apache.maven.continuum.model.scm.ScmResult;
39 import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
40 import org.apache.maven.continuum.project.ContinuumProjectState;
41 import org.apache.maven.continuum.store.ContinuumObjectNotFoundException;
42 import org.apache.maven.continuum.store.ContinuumStoreException;
43 import org.apache.maven.continuum.utils.WorkingDirectoryService;
44 import org.apache.maven.scm.ScmException;
45 import org.apache.maven.scm.ScmFile;
46 import org.apache.maven.scm.command.update.UpdateScmResult;
47 import org.apache.maven.scm.manager.NoSuchScmProviderException;
48 import org.apache.maven.scm.repository.ScmRepositoryException;
49
50
51
52
53
54
55 public class UpdateWorkingDirectoryFromScmContinuumAction
56 extends AbstractContinuumAction
57 {
58 private static final String KEY_UPDATE_SCM_RESULT = "update-result";
59
60
61
62
63 private ContinuumNotificationDispatcher notifier;
64
65
66
67
68 private ContinuumScm scm;
69
70
71
72
73 private WorkingDirectoryService workingDirectoryService;
74
75
76
77
78 private BuildResultDao buildResultDao;
79
80
81
82
83 private ProjectDao projectDao;
84
85 public void execute( Map context )
86 throws ScmRepositoryException, NoSuchScmProviderException, ScmException, ContinuumObjectNotFoundException,
87 ContinuumStoreException
88 {
89 Project project = projectDao.getProject( getProject( context ).getId() );
90
91 BuildDefinition buildDefinition = getBuildDefinition( context );
92
93 UpdateScmResult scmResult;
94
95 ScmResult result;
96
97 Date latestUpdateDate = null;
98
99 int originalState = project.getState();
100
101 project.setState( ContinuumProjectState.UPDATING );
102
103 projectDao.updateProject( project );
104
105 try
106 {
107 BuildResult buildResult = buildResultDao.getLatestBuildResultForProject( project.getId() );
108
109 latestUpdateDate = new Date( buildResult.getStartTime() );
110 }
111 catch ( Exception e )
112 {
113 }
114
115 try
116 {
117 notifier.checkoutStarted( project, buildDefinition );
118
119
120 File workingDirectory = workingDirectoryService.getWorkingDirectory( project );
121 ContinuumScmConfiguration config = createScmConfiguration( project, workingDirectory );
122 config.setLatestUpdateDate( latestUpdateDate );
123 String tag = config.getTag();
124 String msg =
125 project.getName() + "', id: '" + project.getId() + "' to '" + workingDirectory.getAbsolutePath() + "'" +
126 ( tag != null ? " with branch/tag " + tag + "." : "." );
127 getLogger().info( "Updating project: " + msg );
128 scmResult = scm.update( config );
129
130 if ( !scmResult.isSuccess() )
131 {
132 getLogger().warn( "Error while updating the code for project: '" + msg );
133
134 getLogger().warn( "Command output: " + scmResult.getCommandOutput() );
135
136 getLogger().warn( "Provider message: " + scmResult.getProviderMessage() );
137 }
138
139 if ( scmResult.getUpdatedFiles() != null && scmResult.getUpdatedFiles().size() > 0 )
140 {
141 getLogger().info( "Updated " + scmResult.getUpdatedFiles().size() + " files." );
142 }
143
144 result = convertScmResult( scmResult );
145 }
146 catch ( ScmRepositoryException e )
147 {
148 result = new ScmResult();
149
150 result.setSuccess( false );
151
152 result.setProviderMessage( e.getMessage() + ": " + getValidationMessages( e ) );
153
154 getLogger().error( e.getMessage(), e );
155 }
156 catch ( NoSuchScmProviderException e )
157 {
158
159 result = new ScmResult();
160
161 result.setSuccess( false );
162
163 result.setProviderMessage( e.getMessage() );
164
165 getLogger().error( e.getMessage(), e );
166 }
167 catch ( ScmException e )
168 {
169 result = new ScmResult();
170
171 result.setSuccess( false );
172
173 result.setException( ContinuumUtils.throwableMessagesToString( e ) );
174
175 getLogger().error( e.getMessage(), e );
176 }
177 finally
178 {
179
180 try
181 {
182 project = projectDao.getProject( project.getId() );
183
184 project.setState( originalState );
185
186 projectDao.updateProject( project );
187 }
188 catch ( Exception e )
189 {
190
191 getLogger().error( e.getMessage(), e );
192 }
193
194 notifier.checkoutComplete( project, buildDefinition );
195 }
196
197 context.put( KEY_UPDATE_SCM_RESULT, result );
198 AbstractContinuumAction.setProject( context, project );
199 }
200
201 private ContinuumScmConfiguration createScmConfiguration( Project project, File workingDirectory )
202 {
203 ContinuumScmConfiguration config = new ContinuumScmConfiguration();
204 config.setUrl( project.getScmUrl() );
205 config.setUsername( project.getScmUsername() );
206 config.setPassword( project.getScmPassword() );
207 config.setUseCredentialsCache( project.isScmUseCache() );
208 config.setWorkingDirectory( workingDirectory );
209 config.setTag( project.getScmTag() );
210 return config;
211 }
212
213 private ScmResult convertScmResult( UpdateScmResult scmResult )
214 {
215 ScmResult result = new ScmResult();
216
217 result.setCommandLine( maskPassword( scmResult.getCommandLine() ) );
218
219 result.setSuccess( scmResult.isSuccess() );
220
221 result.setCommandOutput( scmResult.getCommandOutput() );
222
223 result.setProviderMessage( scmResult.getProviderMessage() );
224
225 if ( scmResult.getChanges() != null && !scmResult.getChanges().isEmpty() )
226 {
227 for ( org.apache.maven.scm.ChangeSet scmChangeSet : (List<org.apache.maven.scm.ChangeSet>) scmResult.getChanges() )
228 {
229 ChangeSet change = new ChangeSet();
230
231 change.setAuthor( scmChangeSet.getAuthor() );
232
233 change.setComment( scmChangeSet.getComment() );
234
235 if ( scmChangeSet.getDate() != null )
236 {
237 change.setDate( scmChangeSet.getDate().getTime() );
238 }
239
240 if ( scmChangeSet.getFiles() != null )
241 {
242 for ( org.apache.maven.scm.ChangeFile f : (List<org.apache.maven.scm.ChangeFile>) scmChangeSet.getFiles() )
243 {
244 ChangeFile file = new ChangeFile();
245
246 file.setName( f.getName() );
247
248 file.setRevision( f.getRevision() );
249
250 change.addFile( file );
251 }
252 }
253
254 result.addChange( change );
255 }
256 }
257 else
258 {
259
260
261 ChangeSet changeSet = convertScmFileSetToChangeSet( scmResult.getUpdatedFiles() );
262
263 if ( changeSet != null )
264 {
265 result.addChange( changeSet );
266 }
267
268 }
269
270 return result;
271 }
272
273 private static ChangeSet convertScmFileSetToChangeSet( List<ScmFile> files )
274 {
275 ChangeSet changeSet = null;
276
277 if ( files != null && !files.isEmpty() )
278 {
279 changeSet = new ChangeSet();
280
281
282 for ( ScmFile scmFile : files )
283 {
284 ChangeFile file = new ChangeFile();
285
286 file.setName( scmFile.getPath() );
287
288
289
290 file.setStatus( scmFile.getStatus().toString() );
291
292 changeSet.addFile( file );
293 }
294 }
295 return changeSet;
296 }
297
298
299 private String maskPassword( String commandLine )
300 {
301 String cmd = commandLine;
302
303 if ( cmd != null && cmd.startsWith( "svn" ) )
304 {
305 String pwdString = "--password";
306
307 if ( cmd.indexOf( pwdString ) > 0 )
308 {
309 int index = cmd.indexOf( pwdString ) + pwdString.length() + 1;
310
311 int nextSpace = cmd.indexOf( " ", index );
312
313 cmd = cmd.substring( 0, index ) + "********" + cmd.substring( nextSpace );
314 }
315 }
316
317 return cmd;
318 }
319
320 private String getValidationMessages( ScmRepositoryException ex )
321 {
322 List<String> messages = ex.getValidationMessages();
323
324 StringBuffer message = new StringBuffer();
325
326 if ( messages != null && !messages.isEmpty() )
327 {
328 for ( Iterator<String> i = messages.iterator(); i.hasNext(); )
329 {
330 message.append( i.next() );
331
332 if ( i.hasNext() )
333 {
334 message.append( System.getProperty( "line.separator" ) );
335 }
336 }
337 }
338 return message.toString();
339 }
340
341 public static ScmResult getUpdateScmResult( Map<String, Object> context )
342 {
343 return getUpdateScmResult( context, null );
344 }
345
346 public static ScmResult getUpdateScmResult( Map<String, Object> context, ScmResult defaultValue )
347 {
348 return (ScmResult) getObject( context, KEY_UPDATE_SCM_RESULT, defaultValue );
349 }
350 }