Coverage Report - org.apache.maven.plugins.site.SiteDeployMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
SiteDeployMojo
22%
21/96
48%
26/54
13,5
 
 1  
 package org.apache.maven.plugins.site;
 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 org.apache.commons.lang.StringUtils;
 23  
 import org.apache.maven.artifact.manager.WagonConfigurationException;
 24  
 import org.apache.maven.artifact.manager.WagonManager;
 25  
 import org.apache.maven.model.DistributionManagement;
 26  
 import org.apache.maven.model.Site;
 27  
 import org.apache.maven.plugin.AbstractMojo;
 28  
 import org.apache.maven.plugin.MojoExecutionException;
 29  
 import org.apache.maven.plugin.logging.Log;
 30  
 import org.apache.maven.project.MavenProject;
 31  
 import org.apache.maven.settings.Server;
 32  
 import org.apache.maven.settings.Settings;
 33  
 import org.apache.maven.wagon.CommandExecutionException;
 34  
 import org.apache.maven.wagon.CommandExecutor;
 35  
 import org.apache.maven.wagon.ConnectionException;
 36  
 import org.apache.maven.wagon.ResourceDoesNotExistException;
 37  
 import org.apache.maven.wagon.TransferFailedException;
 38  
 import org.apache.maven.wagon.UnsupportedProtocolException;
 39  
 import org.apache.maven.wagon.Wagon;
 40  
 import org.apache.maven.wagon.authentication.AuthenticationException;
 41  
 import org.apache.maven.wagon.authorization.AuthorizationException;
 42  
 import org.apache.maven.wagon.observers.Debug;
 43  
 import org.apache.maven.wagon.proxy.ProxyInfo;
 44  
 import org.apache.maven.wagon.repository.Repository;
 45  
 import org.codehaus.plexus.PlexusConstants;
 46  
 import org.codehaus.plexus.PlexusContainer;
 47  
 import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
 48  
 import org.codehaus.plexus.component.configurator.ComponentConfigurator;
 49  
 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
 50  
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 51  
 import org.codehaus.plexus.configuration.PlexusConfiguration;
 52  
 import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
 53  
 import org.codehaus.plexus.context.Context;
 54  
 import org.codehaus.plexus.context.ContextException;
 55  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 56  
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 57  
 
 58  
 import java.io.File;
 59  
 
 60  
 /**
 61  
  * Deploys the generated site using <code>scp</code> or <code>file</code>
 62  
  * protocol to the site URL specified in the
 63  
  * <code>&lt;distributionManagement&gt;</code> section of the POM.
 64  
  * <p>
 65  
  * For <code>scp</code> protocol, the website files are packaged into zip archive,
 66  
  * then the archive is transfered to the remote host, next it is un-archived.
 67  
  * This method of deployment should normally be much faster
 68  
  * than making a file by file copy.  For <code>file</code> protocol, the files are copied
 69  
  * directly to the destination directory.
 70  
  * </p>
 71  
  *
 72  
  * @author <a href="mailto:michal@org.codehaus.org">Michal Maczka</a>
 73  
  * @version $Id: org.apache.maven.plugins.site.SiteDeployMojo.html 816556 2012-05-08 11:58:34Z hboutemy $
 74  
  * @goal deploy
 75  
  */
 76  0
 public class SiteDeployMojo
 77  
     extends AbstractMojo implements Contextualizable
 78  
 {
 79  
     /**
 80  
      * Directory containing the generated project sites and report distributions.
 81  
      *
 82  
      * @parameter alias="outputDirectory" expression="${project.reporting.outputDirectory}"
 83  
      * @required
 84  
      */
 85  
     private File inputDirectory;
 86  
 
 87  
     /**
 88  
      * Whether to run the "chmod" command on the remote site after the deploy.
 89  
      * Defaults to "true".
 90  
      *
 91  
      * @parameter expression="${maven.site.chmod}" default-value="true"
 92  
      * @since 2.1
 93  
      */
 94  
     private boolean chmod;
 95  
 
 96  
     /**
 97  
      * The mode used by the "chmod" command. Only used if chmod = true.
 98  
      * Defaults to "g+w,a+rX".
 99  
      *
 100  
      * @parameter expression="${maven.site.chmod.mode}" default-value="g+w,a+rX"
 101  
      * @since 2.1
 102  
      */
 103  
     private String chmodMode;
 104  
 
 105  
     /**
 106  
      * The options used by the "chmod" command. Only used if chmod = true.
 107  
      * Defaults to "-Rf".
 108  
      *
 109  
      * @parameter expression="${maven.site.chmod.options}" default-value="-Rf"
 110  
      * @since 2.1
 111  
      */
 112  
     private String chmodOptions;
 113  
 
 114  
     /**
 115  
      * @parameter expression="${project}"
 116  
      * @required
 117  
      * @readonly
 118  
      */
 119  
     private MavenProject project;
 120  
 
 121  
     /**
 122  
      * @component
 123  
      */
 124  
     private WagonManager wagonManager;
 125  
 
 126  
     /**
 127  
      * The current user system settings for use in Maven.
 128  
      *
 129  
      * @parameter expression="${settings}"
 130  
      * @required
 131  
      * @readonly
 132  
      */
 133  
     private Settings settings;
 134  
 
 135  
     private PlexusContainer container;
 136  
 
 137  
     /** {@inheritDoc} */
 138  
     public void execute()
 139  
         throws MojoExecutionException
 140  
     {
 141  0
         if ( !inputDirectory.exists() )
 142  
         {
 143  0
             throw new MojoExecutionException( "The site does not exist, please run site:site first" );
 144  
         }
 145  
 
 146  0
         DistributionManagement distributionManagement = project.getDistributionManagement();
 147  
 
 148  0
         if ( distributionManagement == null )
 149  
         {
 150  0
             throw new MojoExecutionException( "Missing distribution management information in the project" );
 151  
         }
 152  
 
 153  0
         Site site = distributionManagement.getSite();
 154  
 
 155  0
         if ( site == null )
 156  
         {
 157  0
             throw new MojoExecutionException(
 158  
                 "Missing site information in the distribution management element in the project.." );
 159  
         }
 160  
 
 161  0
         String url = site.getUrl();
 162  
 
 163  0
         String id = site.getId();
 164  
 
 165  0
         if ( url == null )
 166  
         {
 167  0
             throw new MojoExecutionException( "The URL to the site is missing in the project descriptor." );
 168  
         }
 169  0
         getLog().debug( "The site will be deployed to '" + url + "'");
 170  
 
 171  0
         Repository repository = new Repository( id, url );
 172  
 
 173  
         // TODO: work on moving this into the deployer like the other deploy methods
 174  
 
 175  
         Wagon wagon;
 176  
 
 177  
         try
 178  
         {
 179  0
             wagon = wagonManager.getWagon( repository );
 180  0
             configureWagon( wagon, repository.getId(), settings, container, getLog() );
 181  
         }
 182  0
         catch ( UnsupportedProtocolException e )
 183  
         {
 184  0
             throw new MojoExecutionException( "Unsupported protocol: '" + repository.getProtocol() + "'", e );
 185  
         }
 186  0
         catch ( WagonConfigurationException e )
 187  
         {
 188  0
             throw new MojoExecutionException( "Unable to configure Wagon: '" + repository.getProtocol() + "'", e );
 189  0
         }
 190  
 
 191  0
         if ( !wagon.supportsDirectoryCopy() )
 192  
         {
 193  0
             throw new MojoExecutionException(
 194  
                 "Wagon protocol '" + repository.getProtocol() + "' doesn't support directory copying" );
 195  
         }
 196  
 
 197  
         try
 198  
         {
 199  0
             Debug debug = new Debug();
 200  
 
 201  0
             wagon.addSessionListener( debug );
 202  
 
 203  0
             wagon.addTransferListener( debug );
 204  
 
 205  0
             ProxyInfo proxyInfo = getProxyInfo( repository, wagonManager );
 206  0
             if ( proxyInfo != null )
 207  
             {
 208  0
                 wagon.connect( repository, wagonManager.getAuthenticationInfo( id ), proxyInfo );
 209  
             }
 210  
             else
 211  
             {
 212  0
                 wagon.connect( repository, wagonManager.getAuthenticationInfo( id ) );
 213  
             }
 214  
 
 215  0
             wagon.putDirectory( inputDirectory, "." );
 216  
 
 217  0
             if ( chmod && wagon instanceof CommandExecutor )
 218  
             {
 219  0
                 CommandExecutor exec = (CommandExecutor) wagon;
 220  0
                 exec.executeCommand( "chmod " + chmodOptions + " " + chmodMode + " " + repository.getBasedir() );
 221  
             }
 222  
         }
 223  0
         catch ( ResourceDoesNotExistException e )
 224  
         {
 225  0
             throw new MojoExecutionException( "Error uploading site", e );
 226  
         }
 227  0
         catch ( TransferFailedException e )
 228  
         {
 229  0
             throw new MojoExecutionException( "Error uploading site", e );
 230  
         }
 231  0
         catch ( AuthorizationException e )
 232  
         {
 233  0
             throw new MojoExecutionException( "Error uploading site", e );
 234  
         }
 235  0
         catch ( ConnectionException e )
 236  
         {
 237  0
             throw new MojoExecutionException( "Error uploading site", e );
 238  
         }
 239  0
         catch ( AuthenticationException e )
 240  
         {
 241  0
             throw new MojoExecutionException( "Error uploading site", e );
 242  
         }
 243  0
         catch ( CommandExecutionException e )
 244  
         {
 245  0
             throw new MojoExecutionException( "Error uploading site", e );
 246  
         }
 247  
         finally
 248  
         {
 249  0
             try
 250  
             {
 251  0
                 wagon.disconnect();
 252  
             }
 253  0
             catch ( ConnectionException e )
 254  
             {
 255  0
                 getLog().error( "Error disconnecting wagon - ignored", e );
 256  0
             }
 257  0
         }
 258  0
     }
 259  
 
 260  
     /**
 261  
      * <p>
 262  
      * Get the <code>ProxyInfo</code> of the proxy associated with the <code>host</code>
 263  
      * and the <code>protocol</code> of the given <code>repository</code>.
 264  
      * </p>
 265  
      * <p>
 266  
      * Extract from <a href="http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html">
 267  
      * J2SE Doc : Networking Properties - nonProxyHosts</a> : "The value can be a list of hosts,
 268  
      * each separated by a |, and in addition a wildcard character (*) can be used for matching"
 269  
      * </p>
 270  
      * <p>
 271  
      * Defensively support for comma (",") and semi colon (";") in addition to pipe ("|") as separator.
 272  
      * </p>
 273  
      *
 274  
      * @param repository the Repository to extract the ProxyInfo from.
 275  
      * @param wagonManager the WagonManager used to connect to the Repository.
 276  
      * @return a ProxyInfo object instantiated or <code>null</code> if no matching proxy is found
 277  
      */
 278  
     public static ProxyInfo getProxyInfo( Repository repository, WagonManager wagonManager )
 279  
     {
 280  11
         ProxyInfo proxyInfo = wagonManager.getProxy( repository.getProtocol() );
 281  
 
 282  11
         if ( proxyInfo == null )
 283  
         {
 284  1
             return null;
 285  
         }
 286  
 
 287  10
         String host = repository.getHost();
 288  10
         String nonProxyHostsAsString = proxyInfo.getNonProxyHosts();
 289  10
         String[] nonProxyHosts = StringUtils.split( nonProxyHostsAsString, ",;|" );
 290  19
         for ( int i = 0; i < nonProxyHosts.length; i++ )
 291  
         {
 292  13
             String nonProxyHost = nonProxyHosts[i];
 293  13
             if ( StringUtils.contains( nonProxyHost, "*" ) )
 294  
             {
 295  
                 // Handle wildcard at the end, beginning or middle of the nonProxyHost
 296  8
                 String nonProxyHostPrefix = StringUtils.substringBefore( nonProxyHost, "*" );
 297  8
                 String nonProxyHostSuffix = StringUtils.substringAfter( nonProxyHost, "*" );
 298  
                 // prefix*
 299  8
                 if ( StringUtils.isNotEmpty( nonProxyHostPrefix ) && host.startsWith( nonProxyHostPrefix )
 300  
                     && StringUtils.isEmpty( nonProxyHostSuffix ) )
 301  
                 {
 302  1
                     return null;
 303  
                 }
 304  
                 // *suffix
 305  7
                 if ( StringUtils.isEmpty( nonProxyHostPrefix )
 306  
                     && StringUtils.isNotEmpty( nonProxyHostSuffix ) && host.endsWith( nonProxyHostSuffix ) )
 307  
                 {
 308  1
                     return null;
 309  
                 }
 310  
                 // prefix*suffix
 311  6
                 if ( StringUtils.isNotEmpty( nonProxyHostPrefix ) && host.startsWith( nonProxyHostPrefix )
 312  
                     && StringUtils.isNotEmpty( nonProxyHostSuffix ) && host.endsWith( nonProxyHostSuffix ) )
 313  
                 {
 314  1
                     return null;
 315  
                 }
 316  5
             }
 317  5
             else if ( host.equals( nonProxyHost ) )
 318  
             {
 319  1
                 return null;
 320  
             }
 321  
         }
 322  6
         return proxyInfo;
 323  
     }
 324  
 
 325  
     /**
 326  
      * Configure the Wagon with the information from serverConfigurationMap ( which comes from settings.xml )
 327  
      *
 328  
      * @todo Remove when {@link WagonManager#getWagon(Repository) is available}. It's available in Maven 2.0.5.
 329  
      * @param wagon
 330  
      * @param repositoryId
 331  
      * @param settings
 332  
      * @param container
 333  
      * @param log
 334  
      * @throws WagonConfigurationException
 335  
      */
 336  
     static void configureWagon( Wagon wagon, String repositoryId, Settings settings, PlexusContainer container,
 337  
                                 Log log )
 338  
         throws WagonConfigurationException
 339  
     {
 340  
         // MSITE-25: Make sure that the server settings are inserted
 341  0
         for ( int i = 0; i < settings.getServers().size(); i++ )
 342  
         {
 343  0
             Server server = (Server) settings.getServers().get( i );
 344  0
             String id = server.getId();
 345  0
             if ( id != null && id.equals( repositoryId ) )
 346  
             {
 347  0
                 if ( server.getConfiguration() != null )
 348  
                 {
 349  0
                     final PlexusConfiguration plexusConf =
 350  
                         new XmlPlexusConfiguration( (Xpp3Dom) server.getConfiguration() );
 351  
 
 352  0
                     ComponentConfigurator componentConfigurator = null;
 353  
                     try
 354  
                     {
 355  0
                         componentConfigurator = (ComponentConfigurator) container.lookup( ComponentConfigurator.ROLE );
 356  0
                         componentConfigurator.configureComponent( wagon, plexusConf, container.getContainerRealm() );
 357  
                     }
 358  0
                     catch ( final ComponentLookupException e )
 359  
                     {
 360  0
                         throw new WagonConfigurationException( repositoryId, "Unable to lookup wagon configurator."
 361  
                             + " Wagon configuration cannot be applied.", e );
 362  
                     }
 363  0
                     catch ( ComponentConfigurationException e )
 364  
                     {
 365  0
                         throw new WagonConfigurationException( repositoryId, "Unable to apply wagon configuration.",
 366  
                                                                e );
 367  
                     }
 368  
                     finally
 369  
                     {
 370  0
                         if ( componentConfigurator != null )
 371  
                         {
 372  
                             try
 373  
                             {
 374  0
                                 container.release( componentConfigurator );
 375  
                             }
 376  0
                             catch ( ComponentLifecycleException e )
 377  
                             {
 378  0
                                 log.error( "Problem releasing configurator - ignoring: " + e.getMessage() );
 379  0
                             }
 380  
                         }
 381  
                     }
 382  
 
 383  
                 }
 384  
 
 385  
             }
 386  
         }
 387  0
     }
 388  
 
 389  
     public void contextualize( Context context )
 390  
         throws ContextException
 391  
     {
 392  0
         container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 393  0
     }
 394  
 
 395  
 }