Coverage Report - org.apache.maven.plugins.site.SiteDeployMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
SiteDeployMojo
20%
20/98
50%
26/52
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 816550 2012-05-08 11:52:49Z 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  
      * @parameter expression="${project}"
 89  
      * @required
 90  
      * @readonly
 91  
      */
 92  
     private MavenProject project;
 93  
 
 94  
     /**
 95  
      * @component
 96  
      */
 97  
     private WagonManager wagonManager;
 98  
 
 99  
     /**
 100  
      * The current user system settings for use in Maven.
 101  
      *
 102  
      * @parameter expression="${settings}"
 103  
      * @required
 104  
      * @readonly
 105  
      */
 106  
     private Settings settings;
 107  
 
 108  
     private PlexusContainer container;
 109  
 
 110  
     public void execute()
 111  
         throws MojoExecutionException
 112  
     {
 113  0
         if ( !inputDirectory.exists() )
 114  
         {
 115  0
             throw new MojoExecutionException( "The site does not exist, please run site:site first" );
 116  
         }
 117  
 
 118  0
         DistributionManagement distributionManagement = project.getDistributionManagement();
 119  
 
 120  0
         if ( distributionManagement == null )
 121  
         {
 122  0
             throw new MojoExecutionException( "Missing distribution management information in the project" );
 123  
         }
 124  
 
 125  0
         Site site = distributionManagement.getSite();
 126  
 
 127  0
         if ( site == null )
 128  
         {
 129  0
             throw new MojoExecutionException(
 130  
                 "Missing site information in the distribution management element in the project.." );
 131  
         }
 132  
 
 133  0
         String url = site.getUrl();
 134  
 
 135  0
         String id = site.getId();
 136  
 
 137  0
         if ( url == null )
 138  
         {
 139  0
             throw new MojoExecutionException( "The URL to the site is missing in the project descriptor." );
 140  
         }
 141  0
         getLog().debug( "The site will be deployed to '" + url + "'");
 142  
 
 143  0
         Repository repository = new Repository( id, url );
 144  
 
 145  
         // TODO: work on moving this into the deployer like the other deploy methods
 146  
 
 147  
         Wagon wagon;
 148  
 
 149  
         try
 150  
         {
 151  0
             wagon = wagonManager.getWagon( repository );
 152  0
             configureWagon( wagon, repository.getId(), settings, container, getLog() );
 153  
         }
 154  0
         catch ( UnsupportedProtocolException e )
 155  
         {
 156  0
             throw new MojoExecutionException( "Unsupported protocol: '" + repository.getProtocol() + "'", e );
 157  
         }
 158  0
         catch ( WagonConfigurationException e )
 159  
         {
 160  0
             throw new MojoExecutionException( "Unable to configure Wagon: '" + repository.getProtocol() + "'", e );
 161  0
         }
 162  
 
 163  0
         if ( !wagon.supportsDirectoryCopy() )
 164  
         {
 165  0
             throw new MojoExecutionException(
 166  
                 "Wagon protocol '" + repository.getProtocol() + "' doesn't support directory copying" );
 167  
         }
 168  
 
 169  
         try
 170  
         {
 171  0
             Debug debug = new Debug();
 172  
 
 173  0
             wagon.addSessionListener( debug );
 174  
 
 175  0
             wagon.addTransferListener( debug );
 176  
 
 177  0
             ProxyInfo proxyInfo = getProxyInfo( repository, wagonManager );
 178  0
             if ( proxyInfo != null )
 179  
             {
 180  0
                 wagon.connect( repository, wagonManager.getAuthenticationInfo( id ), proxyInfo );
 181  
             }
 182  
             else
 183  
             {
 184  0
                 wagon.connect( repository, wagonManager.getAuthenticationInfo( id ) );
 185  
             }
 186  
 
 187  0
             wagon.putDirectory( inputDirectory, "." );
 188  
 
 189  
             // TODO: current wagon uses zip which will use the umask on remote host instead of honouring our settings
 190  
             //  Force group writeable
 191  0
             if ( wagon instanceof CommandExecutor )
 192  
             {
 193  0
                 CommandExecutor exec = (CommandExecutor) wagon;
 194  0
                 exec.executeCommand( "chmod -Rf g+w,a+rX " + repository.getBasedir() );
 195  
             }
 196  0
         }
 197  0
         catch ( ResourceDoesNotExistException e )
 198  
         {
 199  0
             throw new MojoExecutionException( "Error uploading site", e );
 200  
         }
 201  0
         catch ( TransferFailedException e )
 202  
         {
 203  0
             throw new MojoExecutionException( "Error uploading site", e );
 204  
         }
 205  0
         catch ( AuthorizationException e )
 206  
         {
 207  0
             throw new MojoExecutionException( "Error uploading site", e );
 208  
         }
 209  0
         catch ( ConnectionException e )
 210  
         {
 211  0
             throw new MojoExecutionException( "Error uploading site", e );
 212  
         }
 213  0
         catch ( AuthenticationException e )
 214  
         {
 215  0
             throw new MojoExecutionException( "Error uploading site", e );
 216  
         }
 217  0
         catch ( CommandExecutionException e )
 218  
         {
 219  0
             throw new MojoExecutionException( "Error uploading site", e );
 220  
         }
 221  
         finally
 222  
         {
 223  0
             try
 224  
             {
 225  0
                 wagon.disconnect();
 226  
             }
 227  0
             catch ( ConnectionException e )
 228  
             {
 229  0
                 getLog().error( "Error disconnecting wagon - ignored", e );
 230  0
             }
 231  0
         }
 232  0
     }
 233  
 
 234  
     /**
 235  
      * <p>
 236  
      * Get the <code>ProxyInfo</code> of the proxy associated with the <code>host</code>
 237  
      * and the <code>protocol</code> of the given <code>repository</code>.
 238  
      * </p>
 239  
      * <p>
 240  
      * Extract from <a href="http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html">
 241  
      * J2SE Doc : Networking Properties - nonProxyHosts</a> : "The value can be a list of hosts,
 242  
      * each separated by a |, and in addition a wildcard character (*) can be used for matching"
 243  
      * </p>
 244  
      * <p>
 245  
      * Defensively support for comma (",") and semi colon (";") in addition to pipe ("|") as separator.
 246  
      * </p>
 247  
      *
 248  
      * @return a ProxyInfo object instantiated or <code>null</code> if no matching proxy is found
 249  
      */
 250  
     public static ProxyInfo getProxyInfo( Repository repository, WagonManager wagonManager )
 251  
     {
 252  11
         ProxyInfo proxyInfo = wagonManager.getProxy( repository.getProtocol() );
 253  
 
 254  11
         if ( proxyInfo == null )
 255  
         {
 256  1
             return null;
 257  
         }
 258  
 
 259  10
         String host = repository.getHost();
 260  10
         String nonProxyHostsAsString = proxyInfo.getNonProxyHosts();
 261  10
         String[] nonProxyHosts = StringUtils.split( nonProxyHostsAsString, ",;|" );
 262  19
         for ( int i = 0; i < nonProxyHosts.length; i++ )
 263  
         {
 264  13
             String nonProxyHost = nonProxyHosts[i];
 265  13
             if ( StringUtils.contains( nonProxyHost, "*" ) )
 266  
             {
 267  
                 // Handle wildcard at the end, beginning or middle of the nonProxyHost
 268  8
                 String nonProxyHostPrefix = StringUtils.substringBefore( nonProxyHost, "*" );
 269  8
                 String nonProxyHostSuffix = StringUtils.substringAfter( nonProxyHost, "*" );
 270  
                 // prefix*
 271  8
                 if ( StringUtils.isNotEmpty( nonProxyHostPrefix ) && host.startsWith( nonProxyHostPrefix )
 272  
                     && StringUtils.isEmpty( nonProxyHostSuffix ) )
 273  
                 {
 274  1
                     return null;
 275  
                 }
 276  
                 // *suffix
 277  7
                 if ( StringUtils.isEmpty( nonProxyHostPrefix )
 278  
                     && StringUtils.isNotEmpty( nonProxyHostSuffix ) && host.endsWith( nonProxyHostSuffix ) )
 279  
                 {
 280  1
                     return null;
 281  
                 }
 282  
                 // prefix*suffix
 283  6
                 if ( StringUtils.isNotEmpty( nonProxyHostPrefix ) && host.startsWith( nonProxyHostPrefix )
 284  
                     && StringUtils.isNotEmpty( nonProxyHostSuffix ) && host.endsWith( nonProxyHostSuffix ) )
 285  
                 {
 286  1
                     return null;
 287  
                 }
 288  
             }
 289  5
             else if ( host.equals( nonProxyHost ) )
 290  
             {
 291  1
                 return null;
 292  
             }
 293  
         }
 294  6
         return proxyInfo;
 295  
     }
 296  
 
 297  
     /**
 298  
      * Configure the Wagon with the information from serverConfigurationMap ( which comes from settings.xml )
 299  
      *
 300  
      * @todo Remove when {@link WagonManager#getWagon(Repository) is available}. It's available in Maven 2.0.5.
 301  
      * @param wagon
 302  
      * @param repositoryId
 303  
      * @param settings
 304  
      * @param container
 305  
      * @param log
 306  
      * @throws WagonConfigurationException
 307  
      */
 308  
     static void configureWagon( Wagon wagon, String repositoryId, Settings settings, PlexusContainer container,
 309  
                                 Log log )
 310  
         throws WagonConfigurationException
 311  
     {
 312  
         // MSITE-25: Make sure that the server settings are inserted
 313  0
         for ( int i = 0; i < settings.getServers().size(); i++ )
 314  
         {
 315  0
             Server server = (Server) settings.getServers().get( i );
 316  0
             String id = server.getId();
 317  0
             if ( id != null && id.equals( repositoryId ) )
 318  
             {
 319  0
                 if ( server.getConfiguration() != null )
 320  
                 {
 321  0
                     final PlexusConfiguration plexusConf =
 322  
                         new XmlPlexusConfiguration( (Xpp3Dom) server.getConfiguration() );
 323  
 
 324  0
                     ComponentConfigurator componentConfigurator = null;
 325  
                     try
 326  
                     {
 327  0
                         componentConfigurator = (ComponentConfigurator) container.lookup( ComponentConfigurator.ROLE );
 328  0
                         componentConfigurator.configureComponent( wagon, plexusConf, container.getContainerRealm() );
 329  0
                     }
 330  0
                     catch ( final ComponentLookupException e )
 331  
                     {
 332  0
                         throw new WagonConfigurationException( repositoryId, "Unable to lookup wagon configurator."
 333  
                             + " Wagon configuration cannot be applied.", e );
 334  
                     }
 335  0
                     catch ( ComponentConfigurationException e )
 336  
                     {
 337  0
                         throw new WagonConfigurationException( repositoryId, "Unable to apply wagon configuration.",
 338  
                                                                e );
 339  
                     }
 340  
                     finally
 341  
                     {
 342  0
                         if ( componentConfigurator != null )
 343  
                         {
 344  
                             try
 345  
                             {
 346  0
                                 container.release( componentConfigurator );
 347  
                             }
 348  0
                             catch ( ComponentLifecycleException e )
 349  
                             {
 350  0
                                 log.error( "Problem releasing configurator - ignoring: " + e.getMessage() );
 351  0
                             }
 352  
                         }
 353  0
                     }
 354  
 
 355  
                 }
 356  
 
 357  
             }
 358  
         }
 359  0
     }
 360  
 
 361  
     public void contextualize( Context context )
 362  
         throws ContextException
 363  
     {
 364  0
         container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 365  0
     }
 366  
 
 367  
 }