Coverage Report - org.apache.maven.plugins.site.AbstractDeployMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractDeployMojo
43%
96/223
31%
36/116
6,227
AbstractDeployMojo$URIEncoder
0%
0/9
0%
0/18
6,227
 
 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.maven.artifact.manager.WagonManager;
 23  
 import org.apache.maven.doxia.site.decoration.inheritance.URIPathDescriptor;
 24  
 import org.apache.maven.execution.MavenExecutionRequest;
 25  
 import org.apache.maven.execution.MavenSession;
 26  
 import org.apache.maven.model.DistributionManagement;
 27  
 import org.apache.maven.model.Site;
 28  
 import org.apache.maven.plugin.MojoExecutionException;
 29  
 import org.apache.maven.plugin.logging.Log;
 30  
 import org.apache.maven.plugins.annotations.Component;
 31  
 import org.apache.maven.plugins.annotations.Parameter;
 32  
 import org.apache.maven.project.MavenProject;
 33  
 import org.apache.maven.settings.Proxy;
 34  
 import org.apache.maven.settings.Server;
 35  
 import org.apache.maven.settings.Settings;
 36  
 import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
 37  
 import org.apache.maven.settings.crypto.SettingsDecrypter;
 38  
 import org.apache.maven.settings.crypto.SettingsDecryptionResult;
 39  
 import org.apache.maven.wagon.CommandExecutionException;
 40  
 import org.apache.maven.wagon.CommandExecutor;
 41  
 import org.apache.maven.wagon.ConnectionException;
 42  
 import org.apache.maven.wagon.ResourceDoesNotExistException;
 43  
 import org.apache.maven.wagon.TransferFailedException;
 44  
 import org.apache.maven.wagon.UnsupportedProtocolException;
 45  
 import org.apache.maven.wagon.Wagon;
 46  
 import org.apache.maven.wagon.authentication.AuthenticationException;
 47  
 import org.apache.maven.wagon.authentication.AuthenticationInfo;
 48  
 import org.apache.maven.wagon.authorization.AuthorizationException;
 49  
 import org.apache.maven.wagon.observers.Debug;
 50  
 import org.apache.maven.wagon.proxy.ProxyInfo;
 51  
 import org.apache.maven.wagon.repository.Repository;
 52  
 import org.codehaus.classworlds.ClassRealm;
 53  
 import org.codehaus.plexus.PlexusConstants;
 54  
 import org.codehaus.plexus.PlexusContainer;
 55  
 import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
 56  
 import org.codehaus.plexus.component.configurator.ComponentConfigurator;
 57  
 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
 58  
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 59  
 import org.codehaus.plexus.configuration.PlexusConfiguration;
 60  
 import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
 61  
 import org.codehaus.plexus.context.Context;
 62  
 import org.codehaus.plexus.context.ContextException;
 63  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 64  
 import org.codehaus.plexus.util.StringUtils;
 65  
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 66  
 
 67  
 import java.io.File;
 68  
 import java.lang.reflect.Method;
 69  
 import java.net.MalformedURLException;
 70  
 import java.net.URL;
 71  
 import java.util.List;
 72  
 import java.util.Locale;
 73  
 import java.util.Set;
 74  
 
 75  
 /**
 76  
  * Abstract base class for deploy mojos.
 77  
  * Since 2.3 this includes {@link SiteStageMojo} and {@link SiteStageDeployMojo}.
 78  
  *
 79  
  * @author ltheussl
 80  
  * @since 2.3
 81  
  */
 82  6
 public abstract class AbstractDeployMojo
 83  
     extends AbstractSiteMojo
 84  
     implements Contextualizable
 85  
 {
 86  
     /**
 87  
      * Directory containing the generated project sites and report distributions.
 88  
      */
 89  
     @Parameter( alias = "outputDirectory", property = "project.reporting.outputDirectory", required = true )
 90  
     private File inputDirectory;
 91  
 
 92  
     /**
 93  
      * Whether to run the "chmod" command on the remote site after the deploy.
 94  
      * Defaults to "true".
 95  
      *
 96  
      * @since 2.1
 97  
      */
 98  
     @Parameter( property = "maven.site.chmod", defaultValue = "true" )
 99  
     private boolean chmod;
 100  
 
 101  
     /**
 102  
      * The mode used by the "chmod" command. Only used if chmod = true.
 103  
      * Defaults to "g+w,a+rX".
 104  
      *
 105  
      * @since 2.1
 106  
      */
 107  
     @Parameter( property = "maven.site.chmod.mode", defaultValue = "g+w,a+rX" )
 108  
     private String chmodMode;
 109  
 
 110  
     /**
 111  
      * The options used by the "chmod" command. Only used if chmod = true.
 112  
      * Defaults to "-Rf".
 113  
      *
 114  
      * @since 2.1
 115  
      */
 116  
     @Parameter( property = "maven.site.chmod.options", defaultValue = "-Rf" )
 117  
     private String chmodOptions;
 118  
 
 119  
     /**
 120  
      * Set this to 'true' to skip site deployment.
 121  
      *
 122  
      * @since 3.0
 123  
      */
 124  
     @Parameter( property = "maven.site.deploy.skip", defaultValue = "false" )
 125  
 
 126  
     private boolean skipDeploy;
 127  
 
 128  
     /**
 129  
      */
 130  
     @Component
 131  
     private WagonManager wagonManager;
 132  
 
 133  
     /**
 134  
      * The current user system settings for use in Maven.
 135  
      */
 136  
     @Component
 137  
     private Settings settings;
 138  
 
 139  
     /**
 140  
      * @since 3.0-beta-2
 141  
      */
 142  
     @Component
 143  
     protected MavenSession mavenSession;
 144  
 
 145  
     private PlexusContainer container;
 146  
 
 147  
     /**
 148  
      * The String "staging/".
 149  
      */
 150  
     protected static final String DEFAULT_STAGING_DIRECTORY = "staging/";
 151  
 
 152  
     /**
 153  
      * {@inheritDoc}
 154  
      */
 155  
     public void execute()
 156  
         throws MojoExecutionException
 157  
     {
 158  6
         if ( skipDeploy && isDeploy() )
 159  
         {
 160  0
             getLog().info( "maven.site.deploy.skip = true: Skipping site deployment" );
 161  0
             return;
 162  
         }
 163  
 
 164  6
         deployTo( new org.apache.maven.plugins.site.wagon.repository.Repository( getDeployRepositoryID(), appendSlash(
 165  
             getDeployRepositoryURL() ) ) );
 166  6
     }
 167  
 
 168  
     /**
 169  
      * Make sure the given url ends with a slash.
 170  
      *
 171  
      * @param url a String.
 172  
      * @return if url already ends with '/' it is returned unchanged,
 173  
      *         otherwise a '/' character is appended.
 174  
      */
 175  
     protected static String appendSlash( final String url )
 176  
     {
 177  6
         if ( url.endsWith( "/" ) )
 178  
         {
 179  6
             return url;
 180  
         }
 181  
         else
 182  
         {
 183  0
             return url + "/";
 184  
         }
 185  
     }
 186  
 
 187  
     /**
 188  
      * Specifies the id to look up credential settings.
 189  
      *
 190  
      * @return the id to look up credentials for the deploy. Not null.
 191  
      * @throws MojoExecutionException if the ID cannot be determined
 192  
      */
 193  
     protected abstract String getDeployRepositoryID()
 194  
         throws MojoExecutionException;
 195  
 
 196  
     /**
 197  
      * Specifies the target URL for the deploy.
 198  
      * This should be the top-level URL, ie above modules and locale sub-directories.
 199  
      *
 200  
      * @return the url to deploy to. Not null.
 201  
      * @throws MojoExecutionException if the URL cannot be constructed
 202  
      */
 203  
     protected abstract String getDeployRepositoryURL()
 204  
         throws MojoExecutionException;
 205  
 
 206  
     /**
 207  
      * Find the relative path between the distribution URLs of the top parent and the current project.
 208  
      *
 209  
      * @return the relative path or "./" if the two URLs are the same.
 210  
      * @throws MojoExecutionException
 211  
      */
 212  
     protected String getDeployModuleDirectory()
 213  
         throws MojoExecutionException
 214  
     {
 215  6
         String relative = siteTool.getRelativePath( getSite( project ).getUrl(), getRootSite( project ).getUrl() );
 216  
 
 217  
         // SiteTool.getRelativePath() uses File.separatorChar,
 218  
         // so we need to convert '\' to '/' in order for the URL to be valid for Windows users
 219  6
         relative = relative.replace( '\\', '/' );
 220  
 
 221  6
         return ( "".equals( relative ) ) ? "./" : relative;
 222  
     }
 223  
 
 224  
     /**
 225  
      * Use wagon to deploy the generated site to a given repository.
 226  
      *
 227  
      * @param repository the repository to deploy to.
 228  
      *                   This needs to contain a valid, non-null {@link Repository#getId() id}
 229  
      *                   to look up credentials for the deploy, and a valid, non-null
 230  
      *                   {@link Repository#getUrl() scm url} to deploy to.
 231  
      * @throws MojoExecutionException if the deploy fails.
 232  
      */
 233  
     private void deployTo( final Repository repository )
 234  
         throws MojoExecutionException
 235  
     {
 236  6
         if ( !inputDirectory.exists() )
 237  
         {
 238  0
             throw new MojoExecutionException( "The site does not exist, please run site:site first" );
 239  
         }
 240  
 
 241  6
         if ( getLog().isDebugEnabled() )
 242  
         {
 243  0
             getLog().debug( "Deploying to '" + repository.getUrl() + "',\n    Using credentials from server id '"
 244  
                                 + repository.getId() + "'" );
 245  
         }
 246  
 
 247  6
         deploy( inputDirectory, repository );
 248  6
     }
 249  
 
 250  
     private void deploy( final File directory, final Repository repository )
 251  
         throws MojoExecutionException
 252  
     {
 253  
         // TODO: work on moving this into the deployer like the other deploy methods
 254  6
         final Wagon wagon = getWagon( repository, wagonManager );
 255  
 
 256  
         try
 257  
         {
 258  6
             configureWagon( wagon, repository.getId(), settings, container, getLog() );
 259  
         }
 260  0
         catch ( TransferFailedException e )
 261  
         {
 262  0
             throw new MojoExecutionException( "Unable to configure Wagon: '" + repository.getProtocol() + "'", e );
 263  6
         }
 264  
 
 265  
         try
 266  
         {
 267  
             final ProxyInfo proxyInfo;
 268  6
             if ( !isMaven3OrMore() )
 269  
             {
 270  0
                 proxyInfo = getProxyInfo( repository, wagonManager );
 271  
             }
 272  
             else
 273  
             {
 274  
                 try
 275  
                 {
 276  6
                     SettingsDecrypter settingsDecrypter = container.lookup( SettingsDecrypter.class );
 277  
 
 278  6
                     proxyInfo = getProxy( repository, settingsDecrypter );
 279  
                 }
 280  0
                 catch ( ComponentLookupException cle )
 281  
                 {
 282  0
                     throw new MojoExecutionException( "Unable to lookup SettingsDecrypter: " + cle.getMessage(), cle );
 283  6
                 }
 284  
             }
 285  
 
 286  6
             push( directory, repository, wagon, proxyInfo, siteTool.getAvailableLocales( locales ),
 287  
                   getDeployModuleDirectory() );
 288  
 
 289  6
             if ( chmod )
 290  
             {
 291  0
                 chmod( wagon, repository, chmodOptions, chmodMode );
 292  
             }
 293  
         }
 294  
         finally
 295  
         {
 296  0
             try
 297  
             {
 298  6
                 wagon.disconnect();
 299  
             }
 300  0
             catch ( ConnectionException e )
 301  
             {
 302  0
                 getLog().error( "Error disconnecting wagon - ignored", e );
 303  6
             }
 304  0
         }
 305  6
     }
 306  
 
 307  
     /**
 308  
      * Find the build directory of the top level project in the reactor.
 309  
      * If no top level project is found, the build directory of the current project is returned.
 310  
      *
 311  
      * @return the build directory of the top level project.
 312  
      */
 313  
     protected File getTopLevelBuildDirectory()
 314  
     {
 315  
         // Find the top level project in the reactor
 316  0
         final MavenProject topLevelProject = getTopLevelProject( reactorProjects );
 317  
 
 318  
         // Use the top level project's build directory if there is one, otherwise use this project's build directory
 319  
         final File buildDirectory;
 320  
 
 321  0
         if ( topLevelProject == null )
 322  
         {
 323  0
             getLog().debug( "No top level project found in the reactor, using the current project." );
 324  
 
 325  0
             buildDirectory = new File( project.getBuild().getDirectory() );
 326  
         }
 327  
         else
 328  
         {
 329  0
             getLog().debug( "Using the top level project found in the reactor." );
 330  
 
 331  0
             buildDirectory = new File( topLevelProject.getBuild().getDirectory() );
 332  
         }
 333  
 
 334  0
         return buildDirectory;
 335  
     }
 336  
 
 337  
     private Wagon getWagon( final Repository repository, final WagonManager manager )
 338  
         throws MojoExecutionException
 339  
     {
 340  
         final Wagon wagon;
 341  
 
 342  
         try
 343  
         {
 344  6
             wagon = manager.getWagon( repository );
 345  
         }
 346  0
         catch ( UnsupportedProtocolException e )
 347  
         {
 348  0
             String shortMessage = "Unsupported protocol: '" + repository.getProtocol() + "' for site deployment to "
 349  
                 + "distributionManagement.site.url=" + repository.getUrl() + ".";
 350  0
             String longMessage =
 351  
                 "\n" + shortMessage + "\n" + "Currently supported protocols are: " + getSupportedProtocols() + ".\n"
 352  
                     + "    Protocols may be added through wagon providers.\n" + "    For more information, see "
 353  
                     + "http://maven.apache.org/plugins/maven-site-plugin/examples/adding-deploy-protocol.html";
 354  
 
 355  0
             getLog().error( longMessage );
 356  
 
 357  0
             throw new MojoExecutionException( shortMessage );
 358  
         }
 359  0
         catch ( TransferFailedException e )
 360  
         {
 361  0
             throw new MojoExecutionException( "Unable to configure Wagon: '" + repository.getProtocol() + "'", e );
 362  6
         }
 363  
 
 364  6
         if ( !wagon.supportsDirectoryCopy() )
 365  
         {
 366  0
             throw new MojoExecutionException(
 367  
                 "Wagon protocol '" + repository.getProtocol() + "' doesn't support directory copying" );
 368  
         }
 369  
 
 370  6
         return wagon;
 371  
     }
 372  
 
 373  
     private String getSupportedProtocols()
 374  
     {
 375  
         try
 376  
         {
 377  0
             Set<String> protocols = container.lookupMap( Wagon.class ).keySet();
 378  
 
 379  0
             return StringUtils.join( protocols.iterator(), ", " );
 380  
         }
 381  0
         catch ( ComponentLookupException e )
 382  
         {
 383  
             // in the unexpected case there is a problem when instantiating a wagon provider
 384  0
             getLog().error( e );
 385  
         }
 386  0
         return "";
 387  
     }
 388  
 
 389  
     private void push( final File inputDirectory, final Repository repository, final Wagon wagon,
 390  
                        final ProxyInfo proxyInfo, final List<Locale> localesList, final String relativeDir )
 391  
         throws MojoExecutionException
 392  
     {
 393  6
         AuthenticationInfo authenticationInfo = wagonManager.getAuthenticationInfo( repository.getId() );
 394  6
         getLog().debug( "authenticationInfo with id '" + repository.getId() + "': "
 395  
                             + ( ( authenticationInfo == null ) ? "-" : authenticationInfo.getUserName() ) );
 396  
 
 397  
         try
 398  
         {
 399  6
             Debug debug = new Debug();
 400  
 
 401  6
             wagon.addSessionListener( debug );
 402  
 
 403  6
             wagon.addTransferListener( debug );
 404  
 
 405  6
             if ( proxyInfo != null )
 406  
             {
 407  4
                 getLog().debug( "connect with proxyInfo" );
 408  4
                 wagon.connect( repository, authenticationInfo, proxyInfo );
 409  
             }
 410  2
             else if ( proxyInfo == null && authenticationInfo != null )
 411  
             {
 412  2
                 getLog().debug( "connect with authenticationInfo and without proxyInfo" );
 413  2
                 wagon.connect( repository, authenticationInfo );
 414  
             }
 415  
             else
 416  
             {
 417  0
                 getLog().debug( "connect without authenticationInfo and without proxyInfo" );
 418  0
                 wagon.connect( repository );
 419  
             }
 420  
 
 421  6
             getLog().info( "Pushing " + inputDirectory );
 422  
 
 423  
             // Default is first in the list
 424  6
             final String defaultLocale = localesList.get( 0 ).getLanguage();
 425  
 
 426  6
             for ( Locale locale : localesList )
 427  
             {
 428  6
                 if ( locale.getLanguage().equals( defaultLocale ) )
 429  
                 {
 430  
                     // TODO: this also uploads the non-default locales,
 431  
                     // is there a way to exclude directories in wagon?
 432  6
                     getLog().info( "   >>> to " + repository.getUrl() + relativeDir );
 433  
 
 434  6
                     wagon.putDirectory( inputDirectory, relativeDir );
 435  
                 }
 436  
                 else
 437  
                 {
 438  0
                     getLog().info( "   >>> to " + repository.getUrl() + locale.getLanguage() + "/" + relativeDir );
 439  
 
 440  0
                     wagon.putDirectory( new File( inputDirectory, locale.getLanguage() ),
 441  
                                         locale.getLanguage() + "/" + relativeDir );
 442  
                 }
 443  
             }
 444  
         }
 445  0
         catch ( ResourceDoesNotExistException e )
 446  
         {
 447  0
             throw new MojoExecutionException( "Error uploading site", e );
 448  
         }
 449  0
         catch ( TransferFailedException e )
 450  
         {
 451  0
             throw new MojoExecutionException( "Error uploading site", e );
 452  
         }
 453  0
         catch ( AuthorizationException e )
 454  
         {
 455  0
             throw new MojoExecutionException( "Error uploading site", e );
 456  
         }
 457  0
         catch ( ConnectionException e )
 458  
         {
 459  0
             throw new MojoExecutionException( "Error uploading site", e );
 460  
         }
 461  0
         catch ( AuthenticationException e )
 462  
         {
 463  0
             throw new MojoExecutionException( "Error uploading site", e );
 464  6
         }
 465  6
     }
 466  
 
 467  
     private static void chmod( final Wagon wagon, final Repository repository, final String chmodOptions,
 468  
                                final String chmodMode )
 469  
         throws MojoExecutionException
 470  
     {
 471  
         try
 472  
         {
 473  0
             if ( wagon instanceof CommandExecutor )
 474  
             {
 475  0
                 CommandExecutor exec = (CommandExecutor) wagon;
 476  0
                 exec.executeCommand( "chmod " + chmodOptions + " " + chmodMode + " " + repository.getBasedir() );
 477  
             }
 478  
             // else ? silently ignore, FileWagon is not a CommandExecutor!
 479  
         }
 480  0
         catch ( CommandExecutionException e )
 481  
         {
 482  0
             throw new MojoExecutionException( "Error uploading site", e );
 483  0
         }
 484  0
     }
 485  
 
 486  
     /**
 487  
      * <p>
 488  
      * Get the <code>ProxyInfo</code> of the proxy associated with the <code>host</code>
 489  
      * and the <code>protocol</code> of the given <code>repository</code>.
 490  
      * </p>
 491  
      * <p>
 492  
      * Extract from <a href="http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html">
 493  
      * J2SE Doc : Networking Properties - nonProxyHosts</a> : "The value can be a list of hosts,
 494  
      * each separated by a |, and in addition a wildcard character (*) can be used for matching"
 495  
      * </p>
 496  
      * <p>
 497  
      * Defensively support for comma (",") and semi colon (";") in addition to pipe ("|") as separator.
 498  
      * </p>
 499  
      *
 500  
      * @param repository   the Repository to extract the ProxyInfo from.
 501  
      * @param wagonManager the WagonManager used to connect to the Repository.
 502  
      * @return a ProxyInfo object instantiated or <code>null</code> if no matching proxy is found
 503  
      */
 504  
     public static ProxyInfo getProxyInfo( Repository repository, WagonManager wagonManager )
 505  
     {
 506  0
         ProxyInfo proxyInfo = wagonManager.getProxy( repository.getProtocol() );
 507  
 
 508  0
         if ( proxyInfo == null )
 509  
         {
 510  0
             return null;
 511  
         }
 512  
 
 513  0
         String host = repository.getHost();
 514  0
         String nonProxyHostsAsString = proxyInfo.getNonProxyHosts();
 515  0
         for ( String nonProxyHost : StringUtils.split( nonProxyHostsAsString, ",;|" ) )
 516  
         {
 517  0
             if ( StringUtils.contains( nonProxyHost, "*" ) )
 518  
             {
 519  
                 // Handle wildcard at the end, beginning or middle of the nonProxyHost
 520  0
                 final int pos = nonProxyHost.indexOf( '*' );
 521  0
                 String nonProxyHostPrefix = nonProxyHost.substring( 0, pos );
 522  0
                 String nonProxyHostSuffix = nonProxyHost.substring( pos + 1 );
 523  
                 // prefix*
 524  0
                 if ( StringUtils.isNotEmpty( nonProxyHostPrefix ) && host.startsWith( nonProxyHostPrefix )
 525  
                     && StringUtils.isEmpty( nonProxyHostSuffix ) )
 526  
                 {
 527  0
                     return null;
 528  
                 }
 529  
                 // *suffix
 530  0
                 if ( StringUtils.isEmpty( nonProxyHostPrefix ) && StringUtils.isNotEmpty( nonProxyHostSuffix )
 531  
                     && host.endsWith( nonProxyHostSuffix ) )
 532  
                 {
 533  0
                     return null;
 534  
                 }
 535  
                 // prefix*suffix
 536  0
                 if ( StringUtils.isNotEmpty( nonProxyHostPrefix ) && host.startsWith( nonProxyHostPrefix )
 537  
                     && StringUtils.isNotEmpty( nonProxyHostSuffix ) && host.endsWith( nonProxyHostSuffix ) )
 538  
                 {
 539  0
                     return null;
 540  
                 }
 541  0
             }
 542  0
             else if ( host.equals( nonProxyHost ) )
 543  
             {
 544  0
                 return null;
 545  
             }
 546  
         }
 547  0
         return proxyInfo;
 548  
     }
 549  
 
 550  
     /**
 551  
      * Get proxy information for Maven 3.
 552  
      *
 553  
      * @param repository
 554  
      * @param settingsDecrypter
 555  
      * @return
 556  
      */
 557  
     private ProxyInfo getProxy( Repository repository, SettingsDecrypter settingsDecrypter )
 558  
     {
 559  6
         String protocol = repository.getProtocol();
 560  6
         String url = repository.getUrl();
 561  
 
 562  6
         getLog().debug( "repository protocol " + protocol );
 563  
 
 564  6
         String originalProtocol = protocol;
 565  
         // olamy: hackish here protocol (wagon hint in fact !) is dav
 566  
         // but the real protocol (transport layer) is http(s)
 567  
         // and it's the one use in wagon to find the proxy arghhh
 568  
         // so we will check both
 569  6
         if ( StringUtils.equalsIgnoreCase( "dav", protocol ) && url.startsWith( "dav:" ) )
 570  
         {
 571  6
             url = url.substring( 4 );
 572  6
             if ( url.startsWith( "http" ) )
 573  
             {
 574  
                 try
 575  
                 {
 576  6
                     URL urlSite = new URL( url );
 577  6
                     protocol = urlSite.getProtocol();
 578  6
                     getLog().debug( "found dav protocol so transform to real transport protocol " + protocol );
 579  
                 }
 580  0
                 catch ( MalformedURLException e )
 581  
                 {
 582  0
                     getLog().warn( "fail to build URL with " + url );
 583  6
                 }
 584  
 
 585  
             }
 586  
         }
 587  
         else
 588  
         {
 589  0
             getLog().debug( "getProxy 'protocol': " + protocol );
 590  
         }
 591  6
         if ( mavenSession != null && protocol != null )
 592  
         {
 593  4
             MavenExecutionRequest request = mavenSession.getRequest();
 594  
 
 595  4
             if ( request != null )
 596  
             {
 597  4
                 List<Proxy> proxies = request.getProxies();
 598  
 
 599  4
                 if ( proxies != null )
 600  
                 {
 601  4
                     for ( Proxy proxy : proxies )
 602  
                     {
 603  4
                         if ( proxy.isActive() && ( protocol.equalsIgnoreCase( proxy.getProtocol() )
 604  
                             || originalProtocol.equalsIgnoreCase( proxy.getProtocol() ) ) )
 605  
                         {
 606  4
                             SettingsDecryptionResult result =
 607  
                                 settingsDecrypter.decrypt( new DefaultSettingsDecryptionRequest( proxy ) );
 608  4
                             proxy = result.getProxy();
 609  
 
 610  4
                             ProxyInfo proxyInfo = new ProxyInfo();
 611  4
                             proxyInfo.setHost( proxy.getHost() );
 612  
                             // so hackish for wagon the protocol is https for site dav : dav:https://dav.codehaus.org/mojo/
 613  4
                             proxyInfo.setType( protocol ); //proxy.getProtocol() );
 614  4
                             proxyInfo.setPort( proxy.getPort() );
 615  4
                             proxyInfo.setNonProxyHosts( proxy.getNonProxyHosts() );
 616  4
                             proxyInfo.setUserName( proxy.getUsername() );
 617  4
                             proxyInfo.setPassword( proxy.getPassword() );
 618  
 
 619  4
                             getLog().debug( "found proxyInfo " + ( proxyInfo == null
 620  
                                 ? "null"
 621  
                                 : "host:port " + proxyInfo.getHost() + ":" + proxyInfo.getPort() + ", "
 622  
                                     + proxyInfo.getUserName() ) );
 623  
 
 624  4
                             return proxyInfo;
 625  
                         }
 626  
                     }
 627  
                 }
 628  
             }
 629  
         }
 630  2
         getLog().debug( "getProxy 'protocol': " + protocol + " no ProxyInfo found" );
 631  2
         return null;
 632  
     }
 633  
 
 634  
     /**
 635  
      * Configure the Wagon with the information from serverConfigurationMap ( which comes from settings.xml )
 636  
      *
 637  
      * @param wagon
 638  
      * @param repositoryId
 639  
      * @param settings
 640  
      * @param container
 641  
      * @param log
 642  
      * @throws TransferFailedException
 643  
      * @todo Remove when {@link WagonManager#getWagon(Repository) is available}. It's available in Maven 2.0.5.
 644  
      */
 645  
     private static void configureWagon( Wagon wagon, String repositoryId, Settings settings, PlexusContainer container,
 646  
                                         Log log )
 647  
         throws TransferFailedException
 648  
     {
 649  6
         log.debug( " configureWagon " );
 650  
 
 651  
         // MSITE-25: Make sure that the server settings are inserted
 652  6
         for ( Server server : settings.getServers() )
 653  
         {
 654  0
             String id = server.getId();
 655  
 
 656  0
             log.debug( "configureWagon server " + id );
 657  
 
 658  0
             if ( id != null && id.equals( repositoryId ) && ( server.getConfiguration() != null ) )
 659  
             {
 660  0
                 final PlexusConfiguration plexusConf =
 661  
                     new XmlPlexusConfiguration( (Xpp3Dom) server.getConfiguration() );
 662  
 
 663  0
                 ComponentConfigurator componentConfigurator = null;
 664  
                 try
 665  
                 {
 666  0
                     componentConfigurator =
 667  
                         (ComponentConfigurator) container.lookup( ComponentConfigurator.ROLE, "basic" );
 668  0
                     if ( isMaven3OrMore() )
 669  
                     {
 670  0
                         componentConfigurator.configureComponent( wagon, plexusConf,
 671  
                                                                   container.getContainerRealm() );
 672  
                     }
 673  
                     else
 674  
                     {
 675  0
                         configureWagonWithMaven2( componentConfigurator, wagon, plexusConf, container );
 676  
                     }
 677  
                 }
 678  0
                 catch ( final ComponentLookupException e )
 679  
                 {
 680  0
                     throw new TransferFailedException(
 681  
                         "While configuring wagon for \'" + repositoryId + "\': Unable to lookup wagon configurator."
 682  
                             + " Wagon configuration cannot be applied.", e );
 683  
                 }
 684  0
                 catch ( ComponentConfigurationException e )
 685  
                 {
 686  0
                     throw new TransferFailedException( "While configuring wagon for \'" + repositoryId
 687  
                                                            + "\': Unable to apply wagon configuration.", e );
 688  
                 }
 689  
                 finally
 690  
                 {
 691  0
                     if ( componentConfigurator != null )
 692  
                     {
 693  
                         try
 694  
                         {
 695  0
                             container.release( componentConfigurator );
 696  
                         }
 697  0
                         catch ( ComponentLifecycleException e )
 698  
                         {
 699  0
                             log.error( "Problem releasing configurator - ignoring: " + e.getMessage() );
 700  0
                         }
 701  
                     }
 702  
                 }
 703  
             }
 704  0
         }
 705  6
     }
 706  
 
 707  
     private static void configureWagonWithMaven2( ComponentConfigurator componentConfigurator, Wagon wagon,
 708  
                                                   PlexusConfiguration plexusConf, PlexusContainer container )
 709  
         throws ComponentConfigurationException
 710  
     {
 711  
         // in maven 2.x   :
 712  
         // * container.getContainerRealm() -> org.codehaus.classworlds.ClassRealm
 713  
         // * componentConfiguration 3rd param is org.codehaus.classworlds.ClassRealm
 714  
         // so use some reflection see MSITE-609
 715  
         try
 716  
         {
 717  0
             Method methodContainerRealm = container.getClass().getMethod( "getContainerRealm" );
 718  0
             ClassRealm realm = (ClassRealm) methodContainerRealm.invoke( container, null );
 719  
 
 720  0
             Method methodConfigure = componentConfigurator.getClass().getMethod( "configureComponent",
 721  
                                                                                  new Class[]{ Object.class,
 722  
                                                                                      PlexusConfiguration.class,
 723  
                                                                                      ClassRealm.class } );
 724  
 
 725  0
             methodConfigure.invoke( componentConfigurator, wagon, plexusConf, realm );
 726  
         }
 727  0
         catch ( Exception e )
 728  
         {
 729  0
             throw new ComponentConfigurationException(
 730  
                 "fail to configure wagon component for a maven2 use " + e.getMessage(), e );
 731  0
         }
 732  0
     }
 733  
 
 734  
     /**
 735  
      * {@inheritDoc}
 736  
      */
 737  
     public void contextualize( Context context )
 738  
         throws ContextException
 739  
     {
 740  6
         container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 741  6
     }
 742  
 
 743  
     /**
 744  
      * Find the top level parent in the reactor, i.e. the execution root.
 745  
      *
 746  
      * @param reactorProjects The projects in the reactor. May be null in which case null is returned.
 747  
      * @return The top level project in the reactor, or <code>null</code> if none can be found
 748  
      */
 749  
     private static MavenProject getTopLevelProject( List<MavenProject> reactorProjects )
 750  
     {
 751  0
         if ( reactorProjects == null )
 752  
         {
 753  0
             return null;
 754  
         }
 755  
 
 756  0
         for ( MavenProject reactorProject : reactorProjects )
 757  
         {
 758  0
             if ( reactorProject.isExecutionRoot() )
 759  
             {
 760  0
                 return reactorProject;
 761  
             }
 762  
         }
 763  
 
 764  0
         return null;
 765  
     }
 766  
 
 767  
     /**
 768  
      * Extract the distributionManagement site from the given MavenProject.
 769  
      *
 770  
      * @param project the MavenProject. Not null.
 771  
      * @return the project site. Not null.
 772  
      *         Also site.getUrl() and site.getId() are guaranteed to be not null.
 773  
      * @throws MojoExecutionException if any of the site info is missing.
 774  
      */
 775  
     protected static Site getSite( final MavenProject project )
 776  
         throws MojoExecutionException
 777  
     {
 778  18
         final String name =
 779  
             project.getName() + " (" + project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion()
 780  
                 + ")";
 781  
 
 782  18
         final DistributionManagement distributionManagement = project.getDistributionManagement();
 783  
 
 784  18
         if ( distributionManagement == null )
 785  
         {
 786  0
             throw new MojoExecutionException( "Missing distribution management in project " + name );
 787  
         }
 788  
 
 789  18
         final Site site = distributionManagement.getSite();
 790  
 
 791  18
         if ( site == null )
 792  
         {
 793  0
             throw new MojoExecutionException(
 794  
                 "Missing site information in the distribution management of the project " + name );
 795  
         }
 796  
 
 797  18
         if ( site.getUrl() == null || site.getId() == null )
 798  
         {
 799  0
             throw new MojoExecutionException( "Missing site data: specify url and id for project " + name );
 800  
         }
 801  
 
 802  18
         return site;
 803  
     }
 804  
 
 805  
     /**
 806  
      * Extract the distributionManagement site of the top level parent of the given MavenProject.
 807  
      * This climbs up the project hierarchy and returns the site of the last project
 808  
      * for which {@link #getSite(org.apache.maven.project.MavenProject)} returns a site.
 809  
      *
 810  
      * @param project the MavenProject. Not null.
 811  
      * @return the top level site. Not null.
 812  
      *         Also site.getUrl() and site.getId() are guaranteed to be not null.
 813  
      * @throws MojoExecutionException if no site info is found in the tree.
 814  
      */
 815  
     protected Site getRootSite( MavenProject project )
 816  
         throws MojoExecutionException
 817  
     {
 818  12
         Site site = getSite( project );
 819  
 
 820  12
         MavenProject parent = project;
 821  
 
 822  12
         while ( parent.getParent() != null )
 823  
         {
 824  
             // MSITE-585, MNG-1943
 825  0
             parent = siteTool.getParentProject( parent, reactorProjects, localRepository );
 826  
 
 827  0
             Site oldSite = site;
 828  
 
 829  
             try
 830  
             {
 831  0
                 site = getSite( parent );
 832  
             }
 833  0
             catch ( MojoExecutionException e )
 834  
             {
 835  0
                 break;
 836  0
             }
 837  
 
 838  
             // MSITE-600
 839  0
             URIPathDescriptor siteURI = new URIPathDescriptor( URIEncoder.encodeURI( site.getUrl() ), "" );
 840  0
             URIPathDescriptor oldSiteURI = new URIPathDescriptor( URIEncoder.encodeURI( oldSite.getUrl() ), "" );
 841  
 
 842  0
             if ( !siteURI.sameSite( oldSiteURI.getBaseURI() ) )
 843  
             {
 844  0
                 return oldSite;
 845  
             }
 846  0
         }
 847  
 
 848  12
         return site;
 849  
     }
 850  
 
 851  
     /**
 852  
      * Detect if the mojo is staging or deploying.
 853  
      *
 854  
      * @return rue if the mojo is for deploy and not staging
 855  
      */
 856  
     protected boolean isDeploy()
 857  
     {
 858  0
         return true;
 859  
     }
 860  
 
 861  6
     private static class URIEncoder
 862  
     {
 863  
         private static final String MARK = "-_.!~*'()";
 864  
         private static final String RESERVED = ";/?:@&=+$,";
 865  
 
 866  
         public static String encodeURI( final String uriString )
 867  
         {
 868  0
             final char[] chars = uriString.toCharArray();
 869  0
             final StringBuilder uri = new StringBuilder( chars.length );
 870  
 
 871  0
             for ( char c : chars )
 872  
             {
 873  0
                 if ( ( c >= '0' && c <= '9' ) || ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' )
 874  
                         || MARK.indexOf( c ) != -1  || RESERVED.indexOf( c ) != -1 )
 875  
                 {
 876  0
                     uri.append( c );
 877  
                 }
 878  
                 else
 879  
                 {
 880  0
                     uri.append( '%' );
 881  0
                     uri.append( Integer.toHexString( (int) c ) );
 882  
                 }
 883  
             }
 884  0
             return uri.toString();
 885  
         }
 886  
     }
 887  
 }