Save This Page
Home » maven-2.0.9-src » org.apache » maven » artifact » manager » [javadoc | source]
    1   package org.apache.maven.artifact.manager;
    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.net.MalformedURLException;
   25   import java.net.URL;
   26   import java.security.NoSuchAlgorithmException;
   27   import java.util.Collection;
   28   import java.util.HashMap;
   29   import java.util.Iterator;
   30   import java.util.LinkedHashMap;
   31   import java.util.List;
   32   import java.util.Map;
   33   import java.util.Set;
   34   
   35   import org.apache.maven.artifact.Artifact;
   36   import org.apache.maven.artifact.metadata.ArtifactMetadata;
   37   import org.apache.maven.artifact.repository.ArtifactRepository;
   38   import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
   39   import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
   40   import org.apache.maven.artifact.repository.DefaultArtifactRepository;
   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.events.TransferListener;
   50   import org.apache.maven.wagon.observers.ChecksumObserver;
   51   import org.apache.maven.wagon.proxy.ProxyInfo;
   52   import org.apache.maven.wagon.repository.Repository;
   53   import org.apache.maven.wagon.repository.RepositoryPermissions;
   54   import org.codehaus.plexus.PlexusConstants;
   55   import org.codehaus.plexus.PlexusContainer;
   56   import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
   57   import org.codehaus.plexus.component.configurator.ComponentConfigurator;
   58   import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
   59   import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
   60   import org.codehaus.plexus.configuration.PlexusConfiguration;
   61   import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
   62   import org.codehaus.plexus.context.Context;
   63   import org.codehaus.plexus.context.ContextException;
   64   import org.codehaus.plexus.logging.AbstractLogEnabled;
   65   import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
   66   import org.codehaus.plexus.util.FileUtils;
   67   import org.codehaus.plexus.util.xml.Xpp3Dom;
   68   
   69   public class DefaultWagonManager
   70       extends AbstractLogEnabled
   71       implements WagonManager, Contextualizable
   72   {
   73       private static final String WILDCARD = "*";
   74       
   75       private static final String EXTERNAL_WILDCARD = "external:*";
   76   
   77       private PlexusContainer container;
   78   
   79       // TODO: proxies, authentication and mirrors are via settings, and should come in via an alternate method - perhaps
   80       // attached to ArtifactRepository before the method is called (so AR would be composed of WR, not inherit it)
   81       private Map proxies = new HashMap();
   82   
   83       private Map authenticationInfoMap = new HashMap();
   84   
   85       private Map serverPermissionsMap = new HashMap();
   86   
   87       //used LinkedMap to preserve the order.
   88       private Map mirrors = new LinkedHashMap();
   89   
   90       /** Map( String, XmlPlexusConfiguration ) with the repository id and the wagon configuration */
   91       private Map serverConfigurationMap = new HashMap();
   92   
   93       private TransferListener downloadMonitor;
   94   
   95       private boolean online = true;
   96   
   97       private ArtifactRepositoryFactory repositoryFactory;
   98   
   99       private boolean interactive = true;
  100   
  101       private Map availableWagons = new HashMap();
  102   
  103       private RepositoryPermissions defaultRepositoryPermissions;
  104   
  105       // TODO: this leaks the component in the public api - it is never released back to the container
  106       public Wagon getWagon( Repository repository )
  107           throws UnsupportedProtocolException, WagonConfigurationException
  108       {
  109           String protocol = repository.getProtocol();
  110   
  111           if ( protocol == null )
  112           {
  113               throw new UnsupportedProtocolException( "The repository " + repository + " does not specify a protocol" );
  114           }
  115   
  116           Wagon wagon = getWagon( protocol );
  117   
  118           configureWagon( wagon, repository.getId() );
  119   
  120           return wagon;
  121       }
  122   
  123       public Wagon getWagon( String protocol )
  124           throws UnsupportedProtocolException
  125       {
  126           PlexusContainer container = getWagonContainer( protocol );
  127   
  128           Wagon wagon;
  129           try
  130           {
  131               wagon = (Wagon) container.lookup( Wagon.ROLE, protocol );
  132           }
  133           catch ( ComponentLookupException e1 )
  134           {
  135               throw new UnsupportedProtocolException(
  136                   "Cannot find wagon which supports the requested protocol: " + protocol, e1 );
  137           }
  138   
  139           wagon.setInteractive( interactive );
  140   
  141           return wagon;
  142       }
  143   
  144       private PlexusContainer getWagonContainer( String protocol )
  145       {
  146           PlexusContainer container = this.container;
  147   
  148           if ( availableWagons.containsKey( protocol ) )
  149           {
  150               container = (PlexusContainer) availableWagons.get( protocol );
  151           }
  152           return container;
  153       }
  154   
  155       public void putArtifact( File source,
  156                                Artifact artifact,
  157                                ArtifactRepository deploymentRepository )
  158           throws TransferFailedException
  159       {
  160           putRemoteFile( deploymentRepository, source, deploymentRepository.pathOf( artifact ), downloadMonitor );
  161       }
  162   
  163       public void putArtifactMetadata( File source,
  164                                        ArtifactMetadata artifactMetadata,
  165                                        ArtifactRepository repository )
  166           throws TransferFailedException
  167       {
  168           getLogger().info( "Uploading " + artifactMetadata );
  169           putRemoteFile( repository, source, repository.pathOfRemoteRepositoryMetadata( artifactMetadata ), null );
  170       }
  171   
  172       private void putRemoteFile( ArtifactRepository repository,
  173                                   File source,
  174                                   String remotePath,
  175                                   TransferListener downloadMonitor )
  176           throws TransferFailedException
  177       {
  178           failIfNotOnline();
  179   
  180           String protocol = repository.getProtocol();
  181   
  182           Wagon wagon;
  183           try
  184           {
  185               wagon = getWagon( protocol );
  186   
  187               configureWagon( wagon, repository );
  188           }
  189           catch ( UnsupportedProtocolException e )
  190           {
  191               throw new TransferFailedException( "Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e );
  192           }
  193   
  194           if ( downloadMonitor != null )
  195           {
  196               wagon.addTransferListener( downloadMonitor );
  197           }
  198   
  199           Map checksums = new HashMap( 2 );
  200           Map sums = new HashMap( 2 );
  201   
  202           // TODO: configure these on the repository
  203           try
  204           {
  205               ChecksumObserver checksumObserver = new ChecksumObserver( "MD5" );
  206               wagon.addTransferListener( checksumObserver );
  207               checksums.put( "md5", checksumObserver );
  208               checksumObserver = new ChecksumObserver( "SHA-1" );
  209               wagon.addTransferListener( checksumObserver );
  210               checksums.put( "sha1", checksumObserver );
  211           }
  212           catch ( NoSuchAlgorithmException e )
  213           {
  214               throw new TransferFailedException( "Unable to add checksum methods: " + e.getMessage(), e );
  215           }
  216   
  217           try
  218           {
  219               Repository artifactRepository = new Repository( repository.getId(), repository.getUrl() );
  220   
  221               if ( serverPermissionsMap.containsKey( repository.getId() ) )
  222               {
  223                   RepositoryPermissions perms = (RepositoryPermissions) serverPermissionsMap.get( repository.getId() );
  224   
  225                   getLogger().debug(
  226                       "adding permissions to wagon connection: " + perms.getFileMode() + " " + perms.getDirectoryMode() );
  227   
  228                   artifactRepository.setPermissions( perms );
  229               }
  230               else
  231               {
  232                   if ( defaultRepositoryPermissions != null )
  233                   {
  234                       artifactRepository.setPermissions( defaultRepositoryPermissions );
  235                   }
  236                   else
  237                   {
  238                       getLogger().debug( "not adding permissions to wagon connection" );
  239                   }
  240               }
  241   
  242               wagon.connect( artifactRepository, getAuthenticationInfo( repository.getId() ), getProxy( protocol ) );
  243   
  244               wagon.put( source, remotePath );
  245   
  246               wagon.removeTransferListener( downloadMonitor );
  247   
  248               // Pre-store the checksums as any future puts will overwrite them
  249               for ( Iterator i = checksums.keySet().iterator(); i.hasNext(); )
  250               {
  251                   String extension = (String) i.next();
  252                   ChecksumObserver observer = (ChecksumObserver) checksums.get( extension );
  253                   sums.put( extension, observer.getActualChecksum() );
  254               }
  255   
  256               // We do this in here so we can checksum the artifact metadata too, otherwise it could be metadata itself
  257               for ( Iterator i = checksums.keySet().iterator(); i.hasNext(); )
  258               {
  259                   String extension = (String) i.next();
  260   
  261                   // TODO: shouldn't need a file intermediatary - improve wagon to take a stream
  262                   File temp = File.createTempFile( "maven-artifact", null );
  263                   temp.deleteOnExit();
  264                   FileUtils.fileWrite( temp.getAbsolutePath(), (String) sums.get( extension ) );
  265   
  266                   wagon.put( temp, remotePath + "." + extension );
  267               }
  268           }
  269           catch ( ConnectionException e )
  270           {
  271               throw new TransferFailedException( "Connection failed: " + e.getMessage(), e );
  272           }
  273           catch ( AuthenticationException e )
  274           {
  275               throw new TransferFailedException( "Authentication failed: " + e.getMessage(), e );
  276           }
  277           catch ( AuthorizationException e )
  278           {
  279               throw new TransferFailedException( "Authorization failed: " + e.getMessage(), e );
  280           }
  281           catch ( ResourceDoesNotExistException e )
  282           {
  283               throw new TransferFailedException( "Resource to deploy not found: " + e.getMessage(), e );
  284           }
  285           catch ( IOException e )
  286           {
  287               throw new TransferFailedException( "Error creating temporary file for deployment: " + e.getMessage(), e );
  288           }
  289           finally
  290           {
  291               disconnectWagon( wagon );
  292   
  293               releaseWagon( protocol, wagon );
  294           }
  295       }
  296   
  297       public void getArtifact( Artifact artifact,
  298                                List remoteRepositories )
  299           throws TransferFailedException, ResourceDoesNotExistException
  300       {
  301           // TODO [BP]: The exception handling here needs some work
  302           boolean successful = false;
  303           for ( Iterator iter = remoteRepositories.iterator(); iter.hasNext() && !successful; )
  304           {
  305               ArtifactRepository repository = (ArtifactRepository) iter.next();
  306   
  307               try
  308               {
  309                   getArtifact( artifact, repository );
  310   
  311                   successful = artifact.isResolved();
  312               }
  313               catch ( ResourceDoesNotExistException e )
  314               {
  315                   // This one we will eat when looking through remote repositories
  316                   // because we want to cycle through them all before squawking.
  317   
  318                   getLogger().debug( "Unable to get resource '" + artifact.getId() + "' from repository " +
  319                       repository.getId() + " (" + repository.getUrl() + ")" );
  320               }
  321               catch ( TransferFailedException e )
  322               {
  323                   getLogger().debug( "Unable to get resource '" + artifact.getId() + "' from repository " +
  324                       repository.getId() + " (" + repository.getUrl() + ")" );
  325               }
  326           }
  327   
  328           // if it already exists locally we were just trying to force it - ignore the update
  329           if ( !successful && !artifact.getFile().exists() )
  330           {
  331               throw new ResourceDoesNotExistException( "Unable to download the artifact from any repository" );
  332           }
  333       }
  334   
  335       public void getArtifact( Artifact artifact,
  336                                ArtifactRepository repository )
  337           throws TransferFailedException, ResourceDoesNotExistException
  338       {
  339           String remotePath = repository.pathOf( artifact );
  340   
  341           ArtifactRepositoryPolicy policy = artifact.isSnapshot() ? repository.getSnapshots() : repository.getReleases();
  342   
  343           if ( !policy.isEnabled() )
  344           {
  345               getLogger().debug( "Skipping disabled repository " + repository.getId() );
  346           }
  347           else if ( repository.isBlacklisted() )
  348           {
  349               getLogger().debug( "Skipping blacklisted repository " + repository.getId() );
  350           }
  351           else
  352           {
  353               getLogger().debug( "Trying repository " + repository.getId() );
  354               getRemoteFile( getMirrorRepository( repository ), artifact.getFile(), remotePath, downloadMonitor,
  355                                      policy.getChecksumPolicy(), false );
  356               getLogger().debug( "  Artifact resolved" );
  357   
  358               artifact.setResolved( true );
  359           }
  360       }
  361   
  362       public void getArtifactMetadata( ArtifactMetadata metadata,
  363                                        ArtifactRepository repository,
  364                                        File destination,
  365                                        String checksumPolicy )
  366           throws TransferFailedException, ResourceDoesNotExistException
  367       {
  368           String remotePath = repository.pathOfRemoteRepositoryMetadata( metadata );
  369   
  370           getRemoteFile( getMirrorRepository( repository ), destination, remotePath, null, checksumPolicy, true );
  371       }
  372   
  373       public void getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata, ArtifactRepository repository,
  374                                                                File destination, String checksumPolicy )
  375           throws TransferFailedException, ResourceDoesNotExistException
  376       {
  377           String remotePath = repository.pathOfRemoteRepositoryMetadata( metadata );
  378   
  379           getRemoteFile( repository, destination, remotePath, null, checksumPolicy, true );
  380       }
  381   
  382       private void getRemoteFile( ArtifactRepository repository,
  383                                   File destination,
  384                                   String remotePath,
  385                                   TransferListener downloadMonitor,
  386                                   String checksumPolicy,
  387                                   boolean force )
  388           throws TransferFailedException, ResourceDoesNotExistException
  389       {
  390           // TODO: better excetpions - transfer failed is not enough?
  391   
  392           failIfNotOnline();
  393   
  394           String protocol = repository.getProtocol();
  395           Wagon wagon;
  396           try
  397           {
  398               wagon = getWagon( protocol );
  399   
  400               configureWagon( wagon, repository );
  401           }
  402           catch ( UnsupportedProtocolException e )
  403           {
  404               throw new TransferFailedException( "Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e );
  405           }
  406   
  407           if ( downloadMonitor != null )
  408           {
  409               wagon.addTransferListener( downloadMonitor );
  410           }
  411   
  412           // TODO: configure on repository
  413           ChecksumObserver md5ChecksumObserver;
  414           ChecksumObserver sha1ChecksumObserver;
  415           try
  416           {
  417               md5ChecksumObserver = new ChecksumObserver( "MD5" );
  418               wagon.addTransferListener( md5ChecksumObserver );
  419   
  420               sha1ChecksumObserver = new ChecksumObserver( "SHA-1" );
  421               wagon.addTransferListener( sha1ChecksumObserver );
  422           }
  423           catch ( NoSuchAlgorithmException e )
  424           {
  425               throw new TransferFailedException( "Unable to add checksum methods: " + e.getMessage(), e );
  426           }
  427   
  428           File temp = new File( destination + ".tmp" );
  429           temp.deleteOnExit();
  430   
  431           boolean downloaded = false;
  432   
  433           try
  434           {
  435               wagon.connect( new Repository( repository.getId(), repository.getUrl() ),
  436                              getAuthenticationInfo( repository.getId() ), getProxy( protocol ) );
  437   
  438               boolean firstRun = true;
  439               boolean retry = true;
  440   
  441               // this will run at most twice. The first time, the firstRun flag is turned off, and if the retry flag
  442               // is set on the first run, it will be turned off and not re-set on the second try. This is because the
  443               // only way the retry flag can be set is if ( firstRun == true ).
  444               while ( firstRun || retry )
  445               {
  446                   // reset the retry flag.
  447                   retry = false;
  448   
  449                   // This should take care of creating destination directory now on
  450                   if ( destination.exists() && !force )
  451                   {
  452                       try
  453                       {
  454                           downloaded = wagon.getIfNewer( remotePath, temp, destination.lastModified() );
  455                           if ( !downloaded )
  456                           {
  457                               // prevent additional checks of this artifact until it expires again
  458                               destination.setLastModified( System.currentTimeMillis() );
  459                           }
  460                       }
  461                       catch ( UnsupportedOperationException e )
  462                       {
  463                           // older wagons throw this. Just get() instead
  464                           wagon.get( remotePath, temp );
  465                           downloaded = true;
  466                       }
  467                   }
  468                   else
  469                   {
  470                       wagon.get( remotePath, temp );
  471                       downloaded = true;
  472                   }
  473   
  474                   if ( downloaded )
  475                   {
  476                       // keep the checksum files from showing up on the download monitor...
  477                       if ( downloadMonitor != null )
  478                       {
  479                           wagon.removeTransferListener( downloadMonitor );
  480                       }
  481   
  482                       // try to verify the SHA-1 checksum for this file.
  483                       try
  484                       {
  485                           verifyChecksum( sha1ChecksumObserver, destination, temp, remotePath, ".sha1", wagon );
  486                       }
  487                       catch ( ChecksumFailedException e )
  488                       {
  489                           // if we catch a ChecksumFailedException, it means the transfer/read succeeded, but the checksum
  490                           // doesn't match. This could be a problem with the server (ibiblio HTTP-200 error page), so we'll
  491                           // try this up to two times. On the second try, we'll handle it as a bona-fide error, based on the
  492                           // repository's checksum checking policy.
  493                           if ( firstRun )
  494                           {
  495                               getLogger().warn( "*** CHECKSUM FAILED - " + e.getMessage() + " - RETRYING" );
  496                               retry = true;
  497                           }
  498                           else
  499                           {
  500                               handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() );
  501                           }
  502                       }
  503                       catch ( ResourceDoesNotExistException sha1TryException )
  504                       {
  505                           getLogger().debug( "SHA1 not found, trying MD5", sha1TryException );
  506   
  507                           // if this IS NOT a ChecksumFailedException, it was a problem with transfer/read of the checksum
  508                           // file...we'll try again with the MD5 checksum.
  509                           try
  510                           {
  511                               verifyChecksum( md5ChecksumObserver, destination, temp, remotePath, ".md5", wagon );
  512                           }
  513                           catch ( ChecksumFailedException e )
  514                           {
  515                               // if we also fail to verify based on the MD5 checksum, and the checksum transfer/read
  516                               // succeeded, then we need to determine whether to retry or handle it as a failure.
  517                               if ( firstRun )
  518                               {
  519                                   retry = true;
  520                               }
  521                               else
  522                               {
  523                                   handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() );
  524                               }
  525                           }
  526                           catch ( ResourceDoesNotExistException md5TryException )
  527                           {
  528                               // this was a failed transfer, and we don't want to retry.
  529                               handleChecksumFailure( checksumPolicy, "Error retrieving checksum file for " + remotePath,
  530                                                      md5TryException );
  531                           }
  532                       }
  533   
  534                       // reinstate the download monitor...
  535                       if ( downloadMonitor != null )
  536                       {
  537                           wagon.addTransferListener( downloadMonitor );
  538                       }
  539                   }
  540   
  541                   // unset the firstRun flag, so we don't get caught in an infinite loop...
  542                   firstRun = false;
  543               }
  544           }
  545           catch ( ConnectionException e )
  546           {
  547               throw new TransferFailedException( "Connection failed: " + e.getMessage(), e );
  548           }
  549           catch ( AuthenticationException e )
  550           {
  551               throw new TransferFailedException( "Authentication failed: " + e.getMessage(), e );
  552           }
  553           catch ( AuthorizationException e )
  554           {
  555               throw new TransferFailedException( "Authorization failed: " + e.getMessage(), e );
  556           }
  557           finally
  558           {
  559               disconnectWagon( wagon );
  560   
  561               releaseWagon( protocol, wagon );
  562           }
  563   
  564           if ( downloaded )
  565           {
  566               if ( !temp.exists() )
  567               {
  568                   throw new ResourceDoesNotExistException( "Downloaded file does not exist: " + temp );
  569               }
  570   
  571               // The temporary file is named destination + ".tmp" and is done this way to ensure
  572               // that the temporary file is in the same file system as the destination because the
  573               // File.renameTo operation doesn't really work across file systems.
  574               // So we will attempt to do a File.renameTo for efficiency and atomicity, if this fails
  575               // then we will use a brute force copy and delete the temporary file.
  576   
  577               if ( !temp.renameTo( destination ) )
  578               {
  579                   try
  580                   {
  581                       FileUtils.copyFile( temp, destination );
  582   
  583                       temp.delete();
  584                   }
  585                   catch ( IOException e )
  586                   {
  587                       throw new TransferFailedException(
  588                           "Error copying temporary file to the final destination: " + e.getMessage(), e );
  589                   }
  590               }
  591           }
  592       }
  593   
  594       public ArtifactRepository getMirrorRepository( ArtifactRepository repository )
  595       {
  596           ArtifactRepository mirror = getMirror( repository );
  597           if ( mirror != null )
  598           {
  599               String id = mirror.getId();
  600               if ( id == null )
  601               {
  602                   // TODO: this should be illegal in settings.xml
  603                   id = repository.getId();
  604               }
  605   
  606               repository = repositoryFactory.createArtifactRepository( id, mirror.getUrl(),
  607                                                                        repository.getLayout(), repository.getSnapshots(),
  608                                                                        repository.getReleases() );
  609           }
  610           return repository;
  611       }
  612   
  613       private void failIfNotOnline()
  614           throws TransferFailedException
  615       {
  616           if ( !isOnline() )
  617           {
  618               throw new TransferFailedException( "System is offline." );
  619           }
  620       }
  621   
  622       private void handleChecksumFailure( String checksumPolicy,
  623                                           String message,
  624                                           Throwable cause )
  625           throws ChecksumFailedException
  626       {
  627           if ( ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL.equals( checksumPolicy ) )
  628           {
  629               throw new ChecksumFailedException( message, cause );
  630           }
  631           else if ( !ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE.equals( checksumPolicy ) )
  632           {
  633               // warn if it is set to anything other than ignore
  634               getLogger().warn( "*** CHECKSUM FAILED - " + message + " - IGNORING" );
  635           }
  636           // otherwise it is ignore
  637       }
  638   
  639       private void verifyChecksum( ChecksumObserver checksumObserver,
  640                                    File destination,
  641                                    File tempDestination,
  642                                    String remotePath,
  643                                    String checksumFileExtension,
  644                                    Wagon wagon )
  645           throws ResourceDoesNotExistException, TransferFailedException, AuthorizationException
  646       {
  647           try
  648           {
  649               // grab it first, because it's about to change...
  650               String actualChecksum = checksumObserver.getActualChecksum();
  651   
  652               File tempChecksumFile = new File( tempDestination + checksumFileExtension + ".tmp" );
  653               tempChecksumFile.deleteOnExit();
  654               wagon.get( remotePath + checksumFileExtension, tempChecksumFile );
  655   
  656               String expectedChecksum = FileUtils.fileRead( tempChecksumFile );
  657   
  658               // remove whitespaces at the end
  659               expectedChecksum = expectedChecksum.trim();
  660   
  661               // check for 'MD5 (name) = CHECKSUM'
  662               if ( expectedChecksum.startsWith( "MD5" ) )
  663               {
  664                   int lastSpacePos = expectedChecksum.lastIndexOf( ' ' );
  665                   expectedChecksum = expectedChecksum.substring( lastSpacePos + 1 );
  666               }
  667               else
  668               {
  669                   // remove everything after the first space (if available)
  670                   int spacePos = expectedChecksum.indexOf( ' ' );
  671   
  672                   if ( spacePos != -1 )
  673                   {
  674                       expectedChecksum = expectedChecksum.substring( 0, spacePos );
  675                   }
  676               }
  677               if ( expectedChecksum.equalsIgnoreCase( actualChecksum ) )
  678               {
  679                   File checksumFile = new File( destination + checksumFileExtension );
  680                   if ( checksumFile.exists() )
  681                   {
  682                       checksumFile.delete();
  683                   }
  684                   FileUtils.copyFile( tempChecksumFile, checksumFile );
  685               }
  686               else
  687               {
  688                   throw new ChecksumFailedException( "Checksum failed on download: local = '" + actualChecksum +
  689                       "'; remote = '" + expectedChecksum + "'" );
  690               }
  691           }
  692           catch ( IOException e )
  693           {
  694               throw new ChecksumFailedException( "Invalid checksum file", e );
  695           }
  696       }
  697   
  698       
  699       private void disconnectWagon( Wagon wagon )
  700       {
  701           try
  702           {
  703               wagon.disconnect();
  704           }
  705           catch ( ConnectionException e )
  706           {
  707               getLogger().error( "Problem disconnecting from wagon - ignoring: " + e.getMessage() );
  708           }
  709       }
  710   
  711       private void releaseWagon( String protocol,
  712                                  Wagon wagon )
  713       {
  714           PlexusContainer container = getWagonContainer( protocol );
  715           try
  716           {
  717               container.release( wagon );
  718           }
  719           catch ( ComponentLifecycleException e )
  720           {
  721               getLogger().error( "Problem releasing wagon - ignoring: " + e.getMessage() );
  722           }
  723       }
  724   
  725       public ProxyInfo getProxy( String protocol )
  726       {
  727           return (ProxyInfo) proxies.get( protocol );
  728       }
  729   
  730       public AuthenticationInfo getAuthenticationInfo( String id )
  731       {
  732           return (AuthenticationInfo) authenticationInfoMap.get( id );
  733       }
  734   
  735       /**
  736        * This method finds a matching mirror for the selected repository. If there is an exact match, this will be used.
  737        * If there is no exact match, then the list of mirrors is examined to see if a pattern applies.
  738        * 
  739        * @param originalRepository See if there is a mirror for this repository.
  740        * @return the selected mirror or null if none are found.
  741        */
  742       public ArtifactRepository getMirror( ArtifactRepository originalRepository )
  743       {
  744           ArtifactRepository selectedMirror = (ArtifactRepository) mirrors.get( originalRepository.getId() );
  745           if ( null == selectedMirror )
  746           {
  747               // Process the patterns in order. First one that matches wins.
  748               Set keySet = mirrors.keySet();
  749               if ( keySet != null )
  750               {
  751                   Iterator iter = keySet.iterator();
  752                   while ( iter.hasNext() )
  753                   {
  754                       String pattern = (String) iter.next();
  755                       if ( matchPattern( originalRepository, pattern ) )
  756                       {
  757                           selectedMirror = (ArtifactRepository) mirrors.get( pattern );
  758                       }
  759                   }
  760               }
  761   
  762           }
  763           return selectedMirror;
  764       }
  765   
  766       /**
  767        * This method checks if the pattern matches the originalRepository. 
  768        * Valid patterns: 
  769        * * = everything
  770        * external:* = everything not on the localhost and not file based.
  771        * repo,repo1 = repo or repo1
  772        * *,!repo1 = everything except repo1
  773        * 
  774        * @param originalRepository to compare for a match.
  775        * @param pattern used for match. Currently only '*' is supported.
  776        * @return true if the repository is a match to this pattern.
  777        */
  778       public boolean matchPattern( ArtifactRepository originalRepository, String pattern )
  779       {
  780           boolean result = false;
  781           String originalId = originalRepository.getId();
  782   
  783           // simple checks first to short circuit processing below.
  784           if ( WILDCARD.equals( pattern ) || pattern.equals( originalId ) )
  785           {
  786               result = true;
  787           }
  788           else
  789           {
  790               // process the list
  791               String[] repos = pattern.split( "," );
  792               for ( int i = 0; i < repos.length; i++ )
  793               {
  794                   String repo = repos[i];
  795   
  796                   // see if this is a negative match
  797                   if ( repo.length() > 1 && repo.startsWith( "!" ) )
  798                   {
  799                       if ( originalId.equals( repo.substring( 1 ) ) )
  800                       {
  801                           // explicitly exclude. Set result and stop processing.
  802                           result = false;
  803                           break;
  804                       }
  805                   }
  806                   // check for exact match
  807                   else if ( originalId.equals( repo ) )
  808                   {
  809                       result = true;
  810                       break;
  811                   }
  812                   // check for external:*
  813                   else if ( EXTERNAL_WILDCARD.equals( repo ) && isExternalRepo( originalRepository ) )
  814                   {
  815                       result = true;
  816                       // don't stop processing in case a future segment explicitly excludes this repo
  817                   }
  818                   else if ( WILDCARD.equals( repo ) )
  819                   {
  820                       result = true;
  821                       // don't stop processing in case a future segment explicitly excludes this repo
  822                   }
  823               }
  824           }
  825           return result;
  826       }
  827   
  828       /**
  829        * Checks the URL to see if this repository refers to an external repository
  830        * 
  831        * @param originalRepository
  832        * @return true if external.
  833        */
  834       public boolean isExternalRepo( ArtifactRepository originalRepository )
  835       {
  836           try
  837           {
  838               URL url = new URL( originalRepository.getUrl() );
  839               return !( url.getHost().equals( "localhost" ) || url.getHost().equals( "127.0.0.1" ) || url.getProtocol().equals(
  840                                                                                                                                 "file" ) );
  841           }
  842           catch ( MalformedURLException e )
  843           {
  844               // bad url just skip it here. It should have been validated already, but the wagon lookup will deal with it
  845               return false;
  846           }
  847       }
  848       
  849       /**
  850        * Set the proxy used for a particular protocol.
  851        * 
  852        * @param protocol the protocol (required)
  853        * @param host the proxy host name (required)
  854        * @param port the proxy port (required)
  855        * @param username the username for the proxy, or null if there is none
  856        * @param password the password for the proxy, or null if there is none
  857        * @param nonProxyHosts the set of hosts not to use the proxy for. Follows Java system property format:
  858        *            <code>*.foo.com|localhost</code>.
  859        * @todo [BP] would be nice to configure this via plexus in some way
  860        */
  861       public void addProxy( String protocol,
  862                             String host,
  863                             int port,
  864                             String username,
  865                             String password,
  866                             String nonProxyHosts )
  867       {
  868           ProxyInfo proxyInfo = new ProxyInfo();
  869           proxyInfo.setHost( host );
  870           proxyInfo.setType( protocol );
  871           proxyInfo.setPort( port );
  872           proxyInfo.setNonProxyHosts( nonProxyHosts );
  873           proxyInfo.setUserName( username );
  874           proxyInfo.setPassword( password );
  875   
  876           proxies.put( protocol, proxyInfo );
  877       }
  878   
  879       public void contextualize( Context context )
  880           throws ContextException
  881       {
  882           container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
  883       }
  884   
  885       /** @todo I'd rather not be setting this explicitly. */
  886       public void setDownloadMonitor( TransferListener downloadMonitor )
  887       {
  888           this.downloadMonitor = downloadMonitor;
  889       }
  890   
  891       public void addAuthenticationInfo( String repositoryId,
  892                                          String username,
  893                                          String password,
  894                                          String privateKey,
  895                                          String passphrase )
  896       {
  897           AuthenticationInfo authInfo = new AuthenticationInfo();
  898   
  899           authInfo.setUserName( username );
  900   
  901           authInfo.setPassword( password );
  902   
  903           authInfo.setPrivateKey( privateKey );
  904   
  905           authInfo.setPassphrase( passphrase );
  906   
  907           authenticationInfoMap.put( repositoryId, authInfo );
  908       }
  909   
  910       public void addPermissionInfo( String repositoryId,
  911                                      String filePermissions,
  912                                      String directoryPermissions )
  913       {
  914   
  915           RepositoryPermissions permissions = new RepositoryPermissions();
  916           boolean addPermissions = false;
  917   
  918           if ( filePermissions != null )
  919           {
  920               permissions.setFileMode( filePermissions );
  921               addPermissions = true;
  922           }
  923   
  924           if ( directoryPermissions != null )
  925           {
  926               permissions.setDirectoryMode( directoryPermissions );
  927               addPermissions = true;
  928           }
  929   
  930           if ( addPermissions )
  931           {
  932               serverPermissionsMap.put( repositoryId, permissions );
  933           }
  934       }
  935   
  936       public void addMirror( String id,
  937                              String mirrorOf,
  938                              String url )
  939       {
  940           ArtifactRepository mirror = new DefaultArtifactRepository( id, url, null );
  941   
  942           mirrors.put( mirrorOf, mirror );
  943       }
  944   
  945       public void setOnline( boolean online )
  946       {
  947           this.online = online;
  948       }
  949   
  950       public boolean isOnline()
  951       {
  952           return online;
  953       }
  954   
  955       public void setInteractive( boolean interactive )
  956       {
  957           this.interactive = interactive;
  958       }
  959   
  960       public void registerWagons( Collection wagons,
  961                                   PlexusContainer extensionContainer )
  962       {
  963           for ( Iterator i = wagons.iterator(); i.hasNext(); )
  964           {
  965               availableWagons.put( i.next(), extensionContainer );
  966           }
  967       }
  968   
  969       /**
  970        * Applies the server configuration to the wagon
  971        *
  972        * @param wagon      the wagon to configure
  973        * @param repository the repository that has the configuration
  974        * @throws WagonConfigurationException wraps any error given during configuration of the wagon instance
  975        */
  976       private void configureWagon( Wagon wagon,
  977                                    ArtifactRepository repository )
  978           throws WagonConfigurationException
  979       {
  980           configureWagon( wagon, repository.getId() );
  981       }
  982   
  983       private void configureWagon( Wagon wagon,
  984                                    String repositoryId )
  985           throws WagonConfigurationException
  986       {
  987           if ( serverConfigurationMap.containsKey( repositoryId ) )
  988           {
  989               ComponentConfigurator componentConfigurator = null;
  990               try
  991               {
  992                   componentConfigurator = (ComponentConfigurator) container.lookup( ComponentConfigurator.ROLE );
  993                   componentConfigurator.configureComponent( wagon, (PlexusConfiguration) serverConfigurationMap
  994                       .get( repositoryId ), container.getContainerRealm() );
  995               }
  996               catch ( final ComponentLookupException e )
  997               {
  998                   throw new WagonConfigurationException( repositoryId,
  999                                                          "Unable to lookup wagon configurator. Wagon configuration cannot be applied.",
 1000                                                          e );
 1001               }
 1002               catch ( ComponentConfigurationException e )
 1003               {
 1004                   throw new WagonConfigurationException( repositoryId, "Unable to apply wagon configuration.", e );
 1005               }
 1006               finally
 1007               {
 1008                   if ( componentConfigurator != null )
 1009                   {
 1010                       try
 1011                       {
 1012                           container.release( componentConfigurator );
 1013                       }
 1014                       catch ( ComponentLifecycleException e )
 1015                       {
 1016                           getLogger().error( "Problem releasing configurator - ignoring: " + e.getMessage() );
 1017                       }
 1018                   }
 1019   
 1020               }
 1021           }
 1022       }
 1023   
 1024       public void addConfiguration( String repositoryId,
 1025                                     Xpp3Dom configuration )
 1026       {
 1027           if ( repositoryId == null || configuration == null )
 1028           {
 1029               throw new IllegalArgumentException( "arguments can't be null" );
 1030           }
 1031   
 1032           final XmlPlexusConfiguration xmlConf = new XmlPlexusConfiguration( configuration );
 1033   
 1034           serverConfigurationMap.put( repositoryId, xmlConf );
 1035       }
 1036   
 1037       public void setDefaultRepositoryPermissions( RepositoryPermissions defaultRepositoryPermissions )
 1038       {
 1039           this.defaultRepositoryPermissions = defaultRepositoryPermissions;
 1040       }
 1041   }

Save This Page
Home » maven-2.0.9-src » org.apache » maven » artifact » manager » [javadoc | source]