EMMA Coverage Report (generated Sun Sep 18 11:34:27 PHT 2011)
[all classes][org.apache.maven.continuum.core.action]

COVERAGE SUMMARY FOR SOURCE FILE [CheckoutProjectContinuumAction.java]

nameclass, %method, %block, %line, %
CheckoutProjectContinuumAction.java100% (1/1)92%  (11/12)63%  (318/506)65%  (66.1/102)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CheckoutProjectContinuumAction100% (1/1)92%  (11/12)63%  (318/506)65%  (66.1/102)
getValidationMessages (ScmRepositoryException): String 0%   (0/1)0%   (0/36)0%   (0/8)
maskPassword (String): String 100% (1/1)22%  (10/46)38%  (3/8)
execute (Map): void 100% (1/1)65%  (220/336)63%  (39.1/62)
CheckoutProjectContinuumAction (): void 100% (1/1)100% (3/3)100% (1/1)
convertScmResult (CheckOutScmResult): ScmResult 100% (1/1)100% (24/24)100% (6/6)
createScmConfiguration (Project, File, String, String): ContinuumScmConfigura... 100% (1/1)100% (27/27)100% (8/8)
getCheckoutResult (Map, Object): ScmResult 100% (1/1)100% (6/6)100% (1/1)
getScmPassword (Map, String): String 100% (1/1)100% (5/5)100% (1/1)
getScmUsername (Map, String): String 100% (1/1)100% (5/5)100% (1/1)
setCheckoutResult (Map, ScmResult): void 100% (1/1)100% (6/6)100% (2/2)
setScmPassword (Map, String): void 100% (1/1)100% (6/6)100% (2/2)
setScmUsername (Map, String): void 100% (1/1)100% (6/6)100% (2/2)

1package org.apache.maven.continuum.core.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 
22import java.io.File;
23import java.util.Iterator;
24import java.util.List;
25import java.util.Map;
26 
27import org.apache.continuum.dao.BuildDefinitionDao;
28import org.apache.continuum.dao.ProjectDao;
29import org.apache.continuum.scm.ContinuumScm;
30import org.apache.continuum.scm.ContinuumScmConfiguration;
31import org.apache.continuum.utils.ContinuumUtils;
32import org.apache.maven.continuum.model.project.BuildDefinition;
33import org.apache.maven.continuum.model.project.Project;
34import org.apache.maven.continuum.model.scm.ScmResult;
35import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
36import org.apache.maven.continuum.project.ContinuumProjectState;
37import org.apache.maven.continuum.store.ContinuumStoreException;
38import org.apache.maven.scm.ScmException;
39import org.apache.maven.scm.command.checkout.CheckOutScmResult;
40import org.apache.maven.scm.manager.NoSuchScmProviderException;
41import org.apache.maven.scm.repository.ScmRepositoryException;
42import org.codehaus.plexus.util.StringUtils;
43 
44/**
45 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
46 * @version $Id: CheckoutProjectContinuumAction.java 800655 2009-08-04 02:01:14Z ctan $
47 * @plexus.component role="org.codehaus.plexus.action.Action" role-hint="checkout-project"
48 */
49public 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     * @plexus.requirement
62     */
63    private ContinuumNotificationDispatcher notifier;
64 
65    /**
66     * @plexus.requirement
67     */
68    private ContinuumScm scm;
69 
70    /**
71     * @plexus.requirement
72     */
73    private BuildDefinitionDao buildDefinitionDao;
74 
75    /**
76     * @plexus.requirement
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        // Check out the project
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                // TODO: is it more appropriate to return this in the converted result so that it can be presented to
127                // the user?
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            // TODO: this is not making it back into a result of any kind - log it at least. Same is probably the case for ScmException
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            // TODO: do we want this here, or should it be to the logs?
178            // TODO: what throwables do we really get here that we can cope with?
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    // TODO: migrate to the SvnCommandLineUtils version (preferably properly encapsulated in the provider)
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}

[all classes][org.apache.maven.continuum.core.action]
EMMA 2.0.5312 (C) Vladimir Roubtsov