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.Iterator;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.continuum.dao.BuildDefinitionDao;
28 import org.apache.continuum.dao.ProjectDao;
29 import org.apache.continuum.scm.ContinuumScm;
30 import org.apache.continuum.scm.ContinuumScmConfiguration;
31 import org.apache.continuum.utils.ContinuumUtils;
32 import org.apache.maven.continuum.model.project.BuildDefinition;
33 import org.apache.maven.continuum.model.project.Project;
34 import org.apache.maven.continuum.model.scm.ScmResult;
35 import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
36 import org.apache.maven.continuum.project.ContinuumProjectState;
37 import org.apache.maven.continuum.store.ContinuumStoreException;
38 import org.apache.maven.scm.ScmException;
39 import org.apache.maven.scm.command.checkout.CheckOutScmResult;
40 import org.apache.maven.scm.manager.NoSuchScmProviderException;
41 import org.apache.maven.scm.repository.ScmRepositoryException;
42 import org.codehaus.plexus.util.StringUtils;
43
44
45
46
47
48
49 public class CheckoutProjectContinuumAction
50 extends AbstractContinuumAction
51 {
52 private static final String KEY_SCM_USERNAME = "scmUserName";
53
54 private static final String KEY_SCM_PASSWORD = "scmUserPassword";
55
56 private static final String KEY_CHECKOUT_SCM_RESULT = "checkout-result";
57
58 private static final String KEY_PROJECT_RELATIVE_PATH = "project-relative-path";
59
60
61
62
63 private ContinuumNotificationDispatcher notifier;
64
65
66
67
68 private ContinuumScm scm;
69
70
71
72
73 private BuildDefinitionDao buildDefinitionDao;
74
75
76
77
78 private ProjectDao projectDao;
79
80 public void execute( Map context )
81 throws ContinuumStoreException
82 {
83 Project project = projectDao.getProject( getProject( context ).getId() );
84
85 BuildDefinition buildDefinition = getBuildDefinition( context );
86
87 if ( buildDefinition != null )
88 {
89 buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinition.getId() );
90 }
91
92 int originalState = project.getState();
93
94 project.setState( ContinuumProjectState.CHECKING_OUT );
95
96 projectDao.updateProject( project );
97
98 File workingDirectory = getWorkingDirectory( context );
99
100
101
102
103
104 ScmResult result;
105
106 try
107 {
108 String scmUserName = getScmUsername( context, project.getScmUsername() );
109 String scmPassword = getScmPassword( context, project.getScmPassword() );
110 ContinuumScmConfiguration config =
111 createScmConfiguration( project, workingDirectory, scmUserName, scmPassword );
112
113 String tag = config.getTag();
114 getLogger().info(
115 "Checking out project: '" + project.getName() + "', id: '" + project.getId() + "' " + "to '" +
116 workingDirectory + "'" + ( tag != null ? " with branch/tag " + tag + "." : "." ) );
117
118 CheckOutScmResult checkoutResult = scm.checkout( config );
119 if ( StringUtils.isNotEmpty( checkoutResult.getRelativePathProjectDirectory() ) )
120 {
121 context.put( KEY_PROJECT_RELATIVE_PATH, checkoutResult.getRelativePathProjectDirectory() );
122 }
123
124 if ( !checkoutResult.isSuccess() )
125 {
126
127
128 String msg = "Error while checking out the code for project: '" + project.getName() + "', id: '" +
129 project.getId() + "' to '" + workingDirectory.getAbsolutePath() + "'" +
130 ( tag != null ? " with branch/tag " + tag + "." : "." );
131 getLogger().warn( msg );
132
133 getLogger().warn( "Command output: " + checkoutResult.getCommandOutput() );
134
135 getLogger().warn( "Provider message: " + checkoutResult.getProviderMessage() );
136 }
137 else
138 {
139 getLogger().info( "Checked out " + checkoutResult.getCheckedOutFiles().size() + " files." );
140 }
141
142 result = convertScmResult( checkoutResult );
143 }
144 catch ( ScmRepositoryException e )
145 {
146 result = new ScmResult();
147
148 result.setSuccess( false );
149
150 result.setProviderMessage( e.getMessage() + ": " + getValidationMessages( e ) );
151
152 getLogger().error( e.getMessage(), e );
153 }
154 catch ( NoSuchScmProviderException e )
155 {
156
157 result = new ScmResult();
158
159 result.setSuccess( false );
160
161 result.setProviderMessage( e.getMessage() );
162
163 getLogger().error( e.getMessage(), e );
164 }
165 catch ( ScmException e )
166 {
167 result = new ScmResult();
168
169 result.setSuccess( false );
170
171 result.setException( ContinuumUtils.throwableMessagesToString( e ) );
172
173 getLogger().error( e.getMessage(), e );
174 }
175 catch ( Throwable t )
176 {
177
178
179 result = new ScmResult();
180
181 result.setSuccess( false );
182
183 result.setException( ContinuumUtils.throwableMessagesToString( t ) );
184
185 getLogger().error( t.getMessage(), t );
186 }
187 finally
188 {
189 String relativePath = getString( context, KEY_PROJECT_RELATIVE_PATH, "" );
190 if ( StringUtils.isNotEmpty( relativePath ) )
191 {
192 project.setRelativePath( relativePath );
193 }
194
195 project = projectDao.getProject( project.getId() );
196
197 if ( originalState == ContinuumProjectState.NEW )
198 {
199 project.setState( ContinuumProjectState.CHECKEDOUT );
200 }
201 else
202 {
203 project.setState( originalState );
204 }
205
206 projectDao.updateProject( project );
207
208 notifier.checkoutComplete( project, buildDefinition );
209 }
210
211 setCheckoutResult( context, result );
212 setProject( context, project );
213 }
214
215 private ContinuumScmConfiguration createScmConfiguration( Project project, File workingDirectory,
216 String scmUserName, String scmPassword )
217 {
218 ContinuumScmConfiguration config = new ContinuumScmConfiguration();
219 config.setUrl( project.getScmUrl() );
220 config.setUsername( scmUserName );
221 config.setPassword( scmPassword );
222 config.setUseCredentialsCache( project.isScmUseCache() );
223 config.setWorkingDirectory( workingDirectory );
224 config.setTag( project.getScmTag() );
225 return config;
226 }
227
228 private ScmResult convertScmResult( CheckOutScmResult scmResult )
229 {
230 ScmResult result = new ScmResult();
231
232 result.setSuccess( scmResult.isSuccess() );
233
234 result.setCommandLine( maskPassword( scmResult.getCommandLine() ) );
235
236 result.setCommandOutput( scmResult.getCommandOutput() );
237
238 result.setProviderMessage( scmResult.getProviderMessage() );
239
240 return result;
241 }
242
243
244 private String maskPassword( String commandLine )
245 {
246 String cmd = commandLine;
247
248 if ( cmd != null && cmd.startsWith( "svn" ) )
249 {
250 String pwdString = "--password";
251
252 if ( cmd.indexOf( pwdString ) > 0 )
253 {
254 int index = cmd.indexOf( pwdString ) + pwdString.length() + 1;
255
256 int nextSpace = cmd.indexOf( " ", index );
257
258 cmd = cmd.substring( 0, index ) + "********" + cmd.substring( nextSpace );
259 }
260 }
261
262 return cmd;
263 }
264
265 private String getValidationMessages( ScmRepositoryException ex )
266 {
267 List<String> messages = ex.getValidationMessages();
268
269 StringBuffer message = new StringBuffer();
270
271 if ( messages != null && !messages.isEmpty() )
272 {
273 for ( Iterator<String> i = messages.iterator(); i.hasNext(); )
274 {
275 message.append( i.next() );
276
277 if ( i.hasNext() )
278 {
279 message.append( System.getProperty( "line.separator" ) );
280 }
281 }
282 }
283 return message.toString();
284 }
285
286 public static String getScmUsername( Map<String, Object> context, String defaultValue )
287 {
288 return getString( context, KEY_SCM_USERNAME, defaultValue );
289 }
290
291 public static void setScmUsername( Map<String, Object> context, String scmUsername )
292 {
293 context.put( KEY_SCM_USERNAME, scmUsername );
294 }
295
296 public static String getScmPassword( Map<String, Object> context, String defaultValue )
297 {
298 return getString( context, KEY_SCM_PASSWORD, defaultValue );
299 }
300
301 public static void setScmPassword( Map<String, Object> context, String scmPassword )
302 {
303 context.put( KEY_SCM_PASSWORD, scmPassword );
304 }
305
306 public static ScmResult getCheckoutResult( Map<String, Object> context, Object defaultValue )
307 {
308 return (ScmResult) getObject( context, KEY_CHECKOUT_SCM_RESULT, defaultValue );
309 }
310
311 public static void setCheckoutResult( Map<String, Object> context, ScmResult checkoutResult )
312 {
313 context.put( KEY_CHECKOUT_SCM_RESULT, checkoutResult );
314 }
315 }