Coverage Report - org.apache.maven.scm.plugin.AbstractScmMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractScmMojo
70 %
95/134
53 %
50/94
4,778
 
 1  
 package org.apache.maven.scm.plugin;
 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.util.ArrayList;
 25  
 import java.util.Iterator;
 26  
 import java.util.List;
 27  
 import java.util.Map;
 28  
 import java.util.Map.Entry;
 29  
 import java.util.Properties;
 30  
 
 31  
 import org.apache.maven.plugin.AbstractMojo;
 32  
 import org.apache.maven.plugin.MojoExecutionException;
 33  
 import org.apache.maven.scm.ScmBranch;
 34  
 import org.apache.maven.scm.ScmException;
 35  
 import org.apache.maven.scm.ScmFileSet;
 36  
 import org.apache.maven.scm.ScmResult;
 37  
 import org.apache.maven.scm.ScmRevision;
 38  
 import org.apache.maven.scm.ScmTag;
 39  
 import org.apache.maven.scm.ScmVersion;
 40  
 import org.apache.maven.scm.manager.ScmManager;
 41  
 import org.apache.maven.scm.provider.ScmProviderRepository;
 42  
 import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
 43  
 import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
 44  
 import org.apache.maven.scm.repository.ScmRepository;
 45  
 import org.apache.maven.scm.repository.ScmRepositoryException;
 46  
 import org.apache.maven.settings.Server;
 47  
 import org.apache.maven.settings.Settings;
 48  
 import org.apache.maven.shared.model.fileset.FileSet;
 49  
 import org.apache.maven.shared.model.fileset.util.FileSetManager;
 50  
 import org.codehaus.plexus.util.StringUtils;
 51  
 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
 52  
 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;
 53  
 
 54  
 /**
 55  
  * @author <a href="evenisse@apache.org">Emmanuel Venisse</a>
 56  
  * @author Olivier Lamy
 57  
  * @version $Id: AbstractScmMojo.java 1069361 2011-02-10 12:38:18Z bentmann $
 58  
  */
 59  28
 public abstract class AbstractScmMojo
 60  
     extends AbstractMojo
 61  
 {
 62  
     /**
 63  
      * The SCM connection URL.
 64  
      *
 65  
      * @parameter expression="${connectionUrl}" default-value="${project.scm.connection}"
 66  
      */
 67  
     private String connectionUrl;
 68  
 
 69  
     /**
 70  
      * The SCM connection URL for developers.
 71  
      *
 72  
      * @parameter expression="${connectionUrl}" default-value="${project.scm.developerConnection}"
 73  
      */
 74  
     private String developerConnectionUrl;
 75  
 
 76  
     /**
 77  
      * The type of connection to use (connection or developerConnection).
 78  
      *
 79  
      * @parameter expression="${connectionType}" default-value="connection"
 80  
      */
 81  
     private String connectionType;
 82  
 
 83  
     /**
 84  
      * The working directory.
 85  
      *
 86  
      * @parameter expression="${workingDirectory}"
 87  
      */
 88  
     private File workingDirectory;
 89  
 
 90  
     /**
 91  
      * The user name (used by svn, starteam and perforce protocol).
 92  
      *
 93  
      * @parameter expression="${username}"
 94  
      */
 95  
     private String username;
 96  
 
 97  
     /**
 98  
      * The user password (used by svn, starteam and perforce protocol).
 99  
      *
 100  
      * @parameter expression="${password}"
 101  
      */
 102  
     private String password;
 103  
 
 104  
     /**
 105  
      * The private key (used by java svn).
 106  
      *
 107  
      * @parameter expression="${privateKey}"
 108  
      */
 109  
     private String privateKey;
 110  
 
 111  
     /**
 112  
      * The passphrase (used by java svn).
 113  
      *
 114  
      * @parameter expression="${passphrase}"
 115  
      */
 116  
     private String passphrase;
 117  
 
 118  
     /**
 119  
      * The url of tags base directory (used by svn protocol). It is not
 120  
      * necessary to set it if you use the standard svn layout
 121  
      * (branches/tags/trunk).
 122  
      *
 123  
      * @parameter expression="${tagBase}"
 124  
      */
 125  
     private String tagBase;
 126  
 
 127  
     /**
 128  
      * Comma separated list of includes file pattern.
 129  
      *
 130  
      * @parameter expression="${includes}"
 131  
      */
 132  
     private String includes;
 133  
 
 134  
     /**
 135  
      * Comma separated list of excludes file pattern.
 136  
      *
 137  
      * @parameter expression="${excludes}"
 138  
      */
 139  
     private String excludes;
 140  
 
 141  
     /**
 142  
      * @component
 143  
      */
 144  
     private ScmManager manager;
 145  
 
 146  
     /**
 147  
      * When this plugin requires Maven 3.0 as minimum, this component can be removed and o.a.m.s.c.SettingsDecrypter be
 148  
      * used instead.
 149  
      * 
 150  
      * @component roleHint="mng-4384"
 151  
      */
 152  
     private SecDispatcher secDispatcher;
 153  
 
 154  
     /**
 155  
      * The base directory.
 156  
      *
 157  
      * @parameter expression="${basedir}"
 158  
      * @required
 159  
      */
 160  
     private File basedir;
 161  
 
 162  
     /**
 163  
      * @parameter default-value="${settings}"
 164  
      * @required
 165  
      * @readonly
 166  
      */
 167  
     private Settings settings;
 168  
 
 169  
     /**
 170  
      * List of System properties to pass to the JUnit tests.
 171  
      *
 172  
      * @parameter
 173  
      */
 174  
     private Properties systemProperties;
 175  
 
 176  
     /**
 177  
      * List of provider implementations.
 178  
      *
 179  
      * @parameter
 180  
      */
 181  
     private Map<String,String> providerImplementations;
 182  
     
 183  
     /**
 184  
      * Should distributed changes be pushed to the central repository?
 185  
      * For many distributed SCMs like Git, a change like a commit 
 186  
      * is only stored in your local copy of the repository.  Pushing
 187  
      * the change allows your to more easily share it with other users.
 188  
      * 
 189  
      * @parameter expression="${pushChanges}" default-value="true"
 190  
      * @since 1.4
 191  
      */
 192  
     private boolean pushChanges;
 193  
 
 194  
     /** {@inheritDoc} */
 195  
     public void execute()
 196  
         throws MojoExecutionException
 197  
     {
 198  26
         if ( systemProperties != null )
 199  
         {
 200  
             // Add all system properties configured by the user
 201  0
             Iterator<Object> iter = systemProperties.keySet().iterator();
 202  
 
 203  0
             while ( iter.hasNext() )
 204  
             {
 205  0
                 String key = (String) iter.next();
 206  
 
 207  0
                 String value = systemProperties.getProperty( key );
 208  
 
 209  0
                 System.setProperty( key, value );
 210  0
             }
 211  
         }
 212  
 
 213  26
         if ( providerImplementations != null && !providerImplementations.isEmpty() )
 214  
         {
 215  0
             for ( Entry<String,String> entry : providerImplementations.entrySet() )
 216  
             {
 217  0
                 String providerType = entry.getKey();
 218  0
                 String providerImplementation = entry.getValue();
 219  0
                 getLog().info(
 220  
                                "Change the default '" + providerType + "' provider implementation to '"
 221  
                                    + providerImplementation + "'." );
 222  0
                 getScmManager().setScmProviderImplementation( providerType, providerImplementation );
 223  0
             }
 224  
         }
 225  26
     }
 226  
 
 227  
     protected void setConnectionType( String connectionType )
 228  
     {
 229  4
         this.connectionType = connectionType;
 230  4
     }
 231  
 
 232  
     public String getConnectionUrl()
 233  
     {
 234  40
         boolean requireDeveloperConnection = !"connection".equals( connectionType.toLowerCase() );
 235  36
         if ( StringUtils.isNotEmpty( connectionUrl ) && !requireDeveloperConnection )
 236  
         {
 237  36
             return connectionUrl;
 238  
         }
 239  0
         else if ( StringUtils.isNotEmpty( developerConnectionUrl ) )
 240  
         {
 241  0
             return developerConnectionUrl;
 242  
         }
 243  0
         if ( requireDeveloperConnection )
 244  
         {
 245  0
             throw new NullPointerException( "You need to define a developerConnectionUrl parameter" );
 246  
         }
 247  
         else
 248  
         {
 249  0
             throw new NullPointerException( "You need to define a connectionUrl parameter" );
 250  
         }
 251  
     }
 252  
 
 253  
     public void setConnectionUrl( String connectionUrl )
 254  
     {
 255  39
         this.connectionUrl = connectionUrl;
 256  39
     }
 257  
 
 258  
     public File getWorkingDirectory()
 259  
     {
 260  10
         if ( workingDirectory == null )
 261  
         {
 262  0
             return basedir;
 263  
         }
 264  
 
 265  10
         return workingDirectory;
 266  
     }
 267  
 
 268  
     public void setWorkingDirectory( File workingDirectory )
 269  
     {
 270  15
         this.workingDirectory = workingDirectory;
 271  15
     }
 272  
 
 273  
     public ScmManager getScmManager()
 274  
     {
 275  45
         return manager;
 276  
     }
 277  
 
 278  
     public ScmFileSet getFileSet()
 279  
         throws IOException
 280  
     {
 281  10
         if ( includes != null || excludes != null )
 282  
         {
 283  0
             return new ScmFileSet( getWorkingDirectory(), includes, excludes );
 284  
         }
 285  
         else
 286  
         {
 287  10
             return new ScmFileSet( getWorkingDirectory() );
 288  
         }
 289  
     }
 290  
 
 291  
     public ScmRepository getScmRepository()
 292  
         throws ScmException
 293  
     {
 294  
         ScmRepository repository;
 295  
 
 296  
         try
 297  
         {
 298  22
             repository = getScmManager().makeScmRepository( getConnectionUrl() );
 299  
 
 300  21
             ScmProviderRepository providerRepo = repository.getProviderRepository();
 301  
             
 302  21
             providerRepo.setPushChanges( pushChanges );
 303  
 
 304  21
             if ( !StringUtils.isEmpty( username ) )
 305  
             {
 306  0
                 providerRepo.setUser( username );
 307  
             }
 308  
 
 309  21
             if ( !StringUtils.isEmpty( password ) )
 310  
             {
 311  0
                 providerRepo.setPassword( password );
 312  
             }
 313  
 
 314  21
             if ( repository.getProviderRepository() instanceof ScmProviderRepositoryWithHost )
 315  
             {
 316  21
                 ScmProviderRepositoryWithHost repo = (ScmProviderRepositoryWithHost) repository.getProviderRepository();
 317  
 
 318  21
                 loadInfosFromSettings( repo );
 319  
 
 320  21
                 if ( !StringUtils.isEmpty( username ) )
 321  
                 {
 322  1
                     repo.setUser( username );
 323  
                 }
 324  
 
 325  21
                 if ( !StringUtils.isEmpty( password ) )
 326  
                 {
 327  1
                     repo.setPassword( password );
 328  
                 }
 329  
 
 330  21
                 if ( !StringUtils.isEmpty( privateKey ) )
 331  
                 {
 332  0
                     repo.setPrivateKey( privateKey );
 333  
                 }
 334  
 
 335  21
                 if ( !StringUtils.isEmpty( passphrase ) )
 336  
                 {
 337  1
                     repo.setPassphrase( passphrase );
 338  
                 }
 339  
             }
 340  
 
 341  21
             if ( !StringUtils.isEmpty( tagBase ) && repository.getProvider().equals( "svn" ) )
 342  
             {
 343  0
                 SvnScmProviderRepository svnRepo = (SvnScmProviderRepository) repository.getProviderRepository();
 344  
 
 345  0
                 svnRepo.setTagBase( tagBase );
 346  
             }
 347  
         }
 348  0
         catch ( ScmRepositoryException e )
 349  
         {
 350  0
             if ( !e.getValidationMessages().isEmpty() )
 351  
             {
 352  0
                 for ( String message : e.getValidationMessages() )
 353  
                 {
 354  0
                     getLog().error( message );
 355  
                 }
 356  
             }
 357  
 
 358  0
             throw new ScmException( "Can't load the scm provider.", e );
 359  
         }
 360  1
         catch ( Exception e )
 361  
         {
 362  1
             throw new ScmException( "Can't load the scm provider.", e );
 363  21
         }
 364  
 
 365  21
         return repository;
 366  
     }
 367  
 
 368  
     /**
 369  
      * Load username password from settings if user has not set them in JVM properties
 370  
      *
 371  
      * @param repo not null
 372  
      */
 373  
     private void loadInfosFromSettings( ScmProviderRepositoryWithHost repo )
 374  
     {
 375  21
         if ( username == null || password == null )
 376  
         {
 377  21
             String host = repo.getHost();
 378  
 
 379  21
             int port = repo.getPort();
 380  
 
 381  21
             if ( port > 0 )
 382  
             {
 383  0
                 host += ":" + port;
 384  
             }
 385  
 
 386  21
             Server server = this.settings.getServer( host );
 387  
 
 388  21
             if ( server != null )
 389  
             {
 390  1
                 if ( username == null )
 391  
                 {
 392  1
                     username = server.getUsername();
 393  
                 }
 394  
 
 395  1
                 if ( password == null )
 396  
                 {
 397  1
                     password = decrypt( server.getPassword(), host );
 398  
                 }
 399  
 
 400  1
                 if ( privateKey == null )
 401  
                 {
 402  1
                     privateKey = server.getPrivateKey();
 403  
                 }
 404  
 
 405  1
                 if ( passphrase == null )
 406  
                 {
 407  1
                     passphrase = decrypt( server.getPassphrase(), host );
 408  
                 }
 409  
             }
 410  
         }
 411  21
     }
 412  
 
 413  
     private String decrypt( String str, String server )
 414  
     {
 415  
         try
 416  
         {
 417  2
             return secDispatcher.decrypt( str );
 418  
         }
 419  0
         catch ( SecDispatcherException e )
 420  
         {
 421  0
             getLog().warn( "Failed to decrypt password/passphrase for server " + server + ", using auth token as is" );
 422  0
             return str;
 423  
         }
 424  
     }
 425  
 
 426  
     public void checkResult( ScmResult result )
 427  
         throws MojoExecutionException
 428  
     {
 429  19
         if ( !result.isSuccess() )
 430  
         {
 431  1
             getLog().error( "Provider message:" );
 432  
 
 433  1
             getLog().error( result.getProviderMessage() == null ? "" : result.getProviderMessage() );
 434  
 
 435  1
             getLog().error( "Command output:" );
 436  
 
 437  1
             getLog().error( result.getCommandOutput() == null ? "" : result.getCommandOutput() );
 438  
 
 439  1
             throw new MojoExecutionException(
 440  
                 "Command failed." + StringUtils.defaultString( result.getProviderMessage() ) );
 441  
         }
 442  18
     }
 443  
 
 444  
     public String getIncludes()
 445  
     {
 446  13
         return includes;
 447  
     }
 448  
 
 449  
     public void setIncludes( String includes )
 450  
     {
 451  2
         this.includes = includes;
 452  2
     }
 453  
 
 454  
     public String getExcludes()
 455  
     {
 456  13
         return excludes;
 457  
     }
 458  
 
 459  
     public void setExcludes( String excludes )
 460  
     {
 461  2
         this.excludes = excludes;
 462  2
     }
 463  
 
 464  
     public ScmVersion getScmVersion( String versionType, String version )
 465  
         throws MojoExecutionException
 466  
     {
 467  23
         if ( StringUtils.isEmpty( versionType ) && StringUtils.isNotEmpty( version ) )
 468  
         {
 469  0
             throw new MojoExecutionException( "You must specify the version type." );
 470  
         }
 471  
 
 472  23
         if ( StringUtils.isEmpty( version ) )
 473  
         {
 474  21
             return null;
 475  
         }
 476  
 
 477  2
         if ( "branch".equals( versionType ) )
 478  
         {
 479  1
             return new ScmBranch( version );
 480  
         }
 481  
 
 482  1
         if ( "tag".equals( versionType ) )
 483  
         {
 484  1
             return new ScmTag( version );
 485  
         }
 486  
 
 487  0
         if ( "revision".equals( versionType ) )
 488  
         {
 489  0
             return new ScmRevision( version );
 490  
         }
 491  
 
 492  0
         throw new MojoExecutionException( "Unknown '" + versionType + "' version type." );
 493  
     }
 494  
     
 495  
     protected void handleExcludesIncludesAfterCheckoutAndExport( File checkoutDirectory )
 496  
         throws MojoExecutionException
 497  
     {
 498  11
         List<String> includes = new ArrayList<String>();
 499  
 
 500  11
         if ( ! StringUtils.isBlank( this.getIncludes() ) )
 501  
         {
 502  2
             String[] tokens = StringUtils.split( this.getIncludes(), "," );
 503  4
             for ( int i = 0; i < tokens.length; ++i )
 504  
             {
 505  2
                 includes.add( tokens[i] );
 506  
             }
 507  
         }
 508  
 
 509  11
         List<String> excludes = new ArrayList<String>();
 510  
 
 511  11
         if ( ! StringUtils.isBlank( this.getExcludes() ) )
 512  
         {
 513  2
             String[] tokens = StringUtils.split( this.getExcludes(), "," );
 514  6
             for ( int i = 0; i < tokens.length; ++i )
 515  
             {
 516  4
                 excludes.add( tokens[i] );
 517  
             }
 518  
         }
 519  
         
 520  11
         if ( includes.isEmpty() &&  excludes.isEmpty() )
 521  
         {
 522  9
             return;
 523  
         }
 524  
 
 525  2
         FileSetManager fileSetManager = new FileSetManager();
 526  
 
 527  2
         FileSet fileset = new FileSet();
 528  2
         fileset.setDirectory( checkoutDirectory.getAbsolutePath() );
 529  2
         fileset.setIncludes( excludes );//revert the order to do the delete
 530  2
         fileset.setExcludes( includes );
 531  2
         fileset.setUseDefaultExcludes( false );
 532  
 
 533  
         try
 534  
         {
 535  2
             fileSetManager.delete( fileset );
 536  
         }
 537  0
         catch ( IOException e )
 538  
         {
 539  0
             throw new MojoExecutionException( "Error found while cleaning up output directory base on excludes/includes configurations.", e );
 540  2
         }
 541  
 
 542  2
     }
 543  
 }