001 package org.apache.maven.repository.legacy; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.io.File; 023 import java.io.IOException; 024 import java.security.NoSuchAlgorithmException; 025 import java.util.ArrayList; 026 import java.util.HashMap; 027 import java.util.List; 028 import java.util.Map; 029 030 import org.apache.maven.artifact.Artifact; 031 import org.apache.maven.artifact.metadata.ArtifactMetadata; 032 import org.apache.maven.artifact.repository.ArtifactRepository; 033 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; 034 import org.apache.maven.wagon.ConnectionException; 035 import org.apache.maven.wagon.ResourceDoesNotExistException; 036 import org.apache.maven.wagon.TransferFailedException; 037 import org.apache.maven.wagon.UnsupportedProtocolException; 038 import org.apache.maven.wagon.Wagon; 039 import org.apache.maven.wagon.authentication.AuthenticationException; 040 import org.apache.maven.wagon.authentication.AuthenticationInfo; 041 import org.apache.maven.wagon.authorization.AuthorizationException; 042 import org.apache.maven.wagon.events.TransferListener; 043 import org.apache.maven.wagon.observers.ChecksumObserver; 044 import org.apache.maven.wagon.proxy.ProxyInfo; 045 import org.apache.maven.wagon.repository.Repository; 046 import org.codehaus.plexus.PlexusContainer; 047 import org.codehaus.plexus.component.annotations.Component; 048 import org.codehaus.plexus.component.annotations.Requirement; 049 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException; 050 import org.codehaus.plexus.component.repository.exception.ComponentLookupException; 051 import org.codehaus.plexus.logging.Logger; 052 import org.codehaus.plexus.util.FileUtils; 053 054 //TODO: remove the update check manager 055 //TODO: separate into retriever and publisher 056 //TODO: remove hardcoding of checksum logic 057 @Component( role = WagonManager.class ) 058 public class DefaultWagonManager 059 implements WagonManager 060 { 061 private static final String[] CHECKSUM_IDS = { "md5", "sha1" }; 062 063 /** have to match the CHECKSUM_IDS */ 064 private static final String[] CHECKSUM_ALGORITHMS = { "MD5", "SHA-1" }; 065 066 @Requirement 067 private Logger logger; 068 069 @Requirement 070 private PlexusContainer container; 071 072 @Requirement 073 private UpdateCheckManager updateCheckManager; 074 075 // 076 // Retriever 077 // 078 public void getArtifact( Artifact artifact, ArtifactRepository repository, TransferListener downloadMonitor, 079 boolean force ) 080 throws TransferFailedException, ResourceDoesNotExistException 081 { 082 String remotePath = repository.pathOf( artifact ); 083 084 ArtifactRepositoryPolicy policy = artifact.isSnapshot() ? repository.getSnapshots() : repository.getReleases(); 085 086 if ( !policy.isEnabled() ) 087 { 088 logger.debug( "Skipping disabled repository " + repository.getId() + " for resolution of " 089 + artifact.getId() ); 090 } 091 else if ( artifact.isSnapshot() || !artifact.getFile().exists() ) 092 { 093 if ( force || updateCheckManager.isUpdateRequired( artifact, repository ) ) 094 { 095 logger.debug( "Trying repository " + repository.getId() + " for resolution of " + artifact.getId() 096 + " from " + remotePath ); 097 098 try 099 { 100 getRemoteFile( repository, artifact.getFile(), remotePath, downloadMonitor, 101 policy.getChecksumPolicy(), false ); 102 103 updateCheckManager.touch( artifact, repository, null ); 104 } 105 catch ( ResourceDoesNotExistException e ) 106 { 107 updateCheckManager.touch( artifact, repository, null ); 108 throw e; 109 } 110 catch ( TransferFailedException e ) 111 { 112 String error = ( e.getMessage() != null ) ? e.getMessage() : e.getClass().getSimpleName(); 113 updateCheckManager.touch( artifact, repository, error ); 114 throw e; 115 } 116 117 logger.debug( " Artifact " + artifact.getId() + " resolved to " + artifact.getFile() ); 118 119 artifact.setResolved( true ); 120 } 121 else if ( !artifact.getFile().exists() ) 122 { 123 String error = updateCheckManager.getError( artifact, repository ); 124 if ( error != null ) 125 { 126 throw new TransferFailedException( "Failure to resolve " + remotePath + " from " 127 + repository.getUrl() + " was cached in the local repository. " 128 + "Resolution will not be reattempted until the update interval of " + repository.getId() 129 + " has elapsed or updates are forced. Original error: " + error ); 130 } 131 else 132 { 133 throw new ResourceDoesNotExistException( "Failure to resolve " + remotePath + " from " 134 + repository.getUrl() + " was cached in the local repository. " 135 + "Resolution will not be reattempted until the update interval of " + repository.getId() 136 + " has elapsed or updates are forced." ); 137 } 138 } 139 } 140 } 141 142 public void getArtifact( Artifact artifact, List<ArtifactRepository> remoteRepositories, 143 TransferListener downloadMonitor, boolean force ) 144 throws TransferFailedException, ResourceDoesNotExistException 145 { 146 TransferFailedException tfe = null; 147 148 for ( ArtifactRepository repository : remoteRepositories ) 149 { 150 try 151 { 152 getArtifact( artifact, repository, downloadMonitor, force ); 153 154 if ( artifact.isResolved() ) 155 { 156 artifact.setRepository( repository ); 157 break; 158 } 159 } 160 catch ( ResourceDoesNotExistException e ) 161 { 162 // This one we will eat when looking through remote repositories 163 // because we want to cycle through them all before squawking. 164 165 logger.debug( "Unable to find artifact " + artifact.getId() + " in repository " + repository.getId() 166 + " (" + repository.getUrl() + ")", e ); 167 } 168 catch ( TransferFailedException e ) 169 { 170 tfe = e; 171 172 String msg = 173 "Unable to get artifact " + artifact.getId() + " from repository " + repository.getId() + " (" 174 + repository.getUrl() + "): " + e.getMessage(); 175 if ( logger.isDebugEnabled() ) 176 { 177 logger.warn( msg, e ); 178 } 179 else 180 { 181 logger.warn( msg ); 182 } 183 } 184 } 185 186 // if it already exists locally we were just trying to force it - ignore the update 187 if ( !artifact.getFile().exists() ) 188 { 189 if ( tfe != null ) 190 { 191 throw tfe; 192 } 193 else 194 { 195 throw new ResourceDoesNotExistException( "Unable to download the artifact from any repository" ); 196 } 197 } 198 } 199 200 public void getArtifactMetadata( ArtifactMetadata metadata, ArtifactRepository repository, File destination, 201 String checksumPolicy ) 202 throws TransferFailedException, ResourceDoesNotExistException 203 { 204 String remotePath = repository.pathOfRemoteRepositoryMetadata( metadata ); 205 206 getRemoteFile( repository, destination, remotePath, null, checksumPolicy, true ); 207 } 208 209 public void getArtifactMetadataFromDeploymentRepository( ArtifactMetadata metadata, ArtifactRepository repository, 210 File destination, String checksumPolicy ) 211 throws TransferFailedException, ResourceDoesNotExistException 212 { 213 String remotePath = repository.pathOfRemoteRepositoryMetadata( metadata ); 214 215 getRemoteFile( repository, destination, remotePath, null, checksumPolicy, true ); 216 } 217 218 /** 219 * Deal with connecting to a wagon repository taking into account authentication and proxies. 220 * 221 * @param wagon 222 * @param repository 223 * @throws ConnectionException 224 * @throws AuthenticationException 225 */ 226 private void connectWagon( Wagon wagon, ArtifactRepository repository ) 227 throws ConnectionException, AuthenticationException 228 { 229 if ( repository.getProxy() != null && logger.isDebugEnabled() ) 230 { 231 logger.debug( "Using proxy " + repository.getProxy().getHost() + ":" + repository.getProxy().getPort() 232 + " for " + repository.getUrl() ); 233 } 234 235 if ( repository.getAuthentication() != null && repository.getProxy() != null ) 236 { 237 wagon.connect( new Repository( repository.getId(), repository.getUrl() ), authenticationInfo( repository ), 238 proxyInfo( repository ) ); 239 } 240 else if ( repository.getAuthentication() != null ) 241 { 242 wagon.connect( new Repository( repository.getId(), repository.getUrl() ), 243 authenticationInfo( repository ) ); 244 } 245 else if ( repository.getProxy() != null ) 246 { 247 wagon.connect( new Repository( repository.getId(), repository.getUrl() ), proxyInfo( repository ) ); 248 } 249 else 250 { 251 wagon.connect( new Repository( repository.getId(), repository.getUrl() ) ); 252 } 253 } 254 255 private AuthenticationInfo authenticationInfo( ArtifactRepository repository ) 256 { 257 AuthenticationInfo ai = new AuthenticationInfo(); 258 ai.setUserName( repository.getAuthentication().getUsername() ); 259 ai.setPassword( repository.getAuthentication().getPassword() ); 260 return ai; 261 } 262 263 private ProxyInfo proxyInfo( ArtifactRepository repository ) 264 { 265 ProxyInfo proxyInfo = new ProxyInfo(); 266 proxyInfo.setHost( repository.getProxy().getHost() ); 267 proxyInfo.setType( repository.getProxy().getProtocol() ); 268 proxyInfo.setPort( repository.getProxy().getPort() ); 269 proxyInfo.setNonProxyHosts( repository.getProxy().getNonProxyHosts() ); 270 proxyInfo.setUserName( repository.getProxy().getUserName() ); 271 proxyInfo.setPassword( repository.getProxy().getPassword() ); 272 return proxyInfo; 273 } 274 275 public void getRemoteFile( ArtifactRepository repository, File destination, String remotePath, 276 TransferListener downloadMonitor, String checksumPolicy, boolean force ) 277 throws TransferFailedException, ResourceDoesNotExistException 278 { 279 String protocol = repository.getProtocol(); 280 281 Wagon wagon; 282 283 try 284 { 285 wagon = getWagon( protocol ); 286 } 287 catch ( UnsupportedProtocolException e ) 288 { 289 throw new TransferFailedException( "Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e ); 290 } 291 292 if ( downloadMonitor != null ) 293 { 294 wagon.addTransferListener( downloadMonitor ); 295 } 296 297 File temp = new File( destination + ".tmp" ); 298 299 temp.deleteOnExit(); 300 301 boolean downloaded = false; 302 303 try 304 { 305 connectWagon( wagon, repository ); 306 307 boolean firstRun = true; 308 boolean retry = true; 309 310 // this will run at most twice. The first time, the firstRun flag is turned off, and if the retry flag 311 // is set on the first run, it will be turned off and not re-set on the second try. This is because the 312 // only way the retry flag can be set is if ( firstRun == true ). 313 while ( firstRun || retry ) 314 { 315 ChecksumObserver md5ChecksumObserver = null; 316 ChecksumObserver sha1ChecksumObserver = null; 317 try 318 { 319 // TODO: configure on repository 320 int i = 0; 321 322 md5ChecksumObserver = addChecksumObserver( wagon, CHECKSUM_ALGORITHMS[i++] ); 323 sha1ChecksumObserver = addChecksumObserver( wagon, CHECKSUM_ALGORITHMS[i++] ); 324 325 // reset the retry flag. 326 retry = false; 327 328 // This should take care of creating destination directory now on 329 if ( destination.exists() && !force ) 330 { 331 try 332 { 333 downloaded = wagon.getIfNewer( remotePath, temp, destination.lastModified() ); 334 335 if ( !downloaded ) 336 { 337 // prevent additional checks of this artifact until it expires again 338 destination.setLastModified( System.currentTimeMillis() ); 339 } 340 } 341 catch ( UnsupportedOperationException e ) 342 { 343 // older wagons throw this. Just get() instead 344 wagon.get( remotePath, temp ); 345 346 downloaded = true; 347 } 348 } 349 else 350 { 351 wagon.get( remotePath, temp ); 352 downloaded = true; 353 } 354 } 355 finally 356 { 357 wagon.removeTransferListener( md5ChecksumObserver ); 358 wagon.removeTransferListener( sha1ChecksumObserver ); 359 } 360 361 if ( downloaded ) 362 { 363 // keep the checksum files from showing up on the download monitor... 364 if ( downloadMonitor != null ) 365 { 366 wagon.removeTransferListener( downloadMonitor ); 367 } 368 369 // try to verify the SHA-1 checksum for this file. 370 try 371 { 372 verifyChecksum( sha1ChecksumObserver, destination, temp, remotePath, ".sha1", wagon ); 373 } 374 catch ( ChecksumFailedException e ) 375 { 376 // if we catch a ChecksumFailedException, it means the transfer/read succeeded, but the checksum 377 // doesn't match. This could be a problem with the server (ibiblio HTTP-200 error page), so we'll 378 // try this up to two times. On the second try, we'll handle it as a bona-fide error, based on the 379 // repository's checksum checking policy. 380 if ( firstRun ) 381 { 382 logger.warn( "*** CHECKSUM FAILED - " + e.getMessage() + " - RETRYING" ); 383 retry = true; 384 } 385 else 386 { 387 handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() ); 388 } 389 } 390 catch ( ResourceDoesNotExistException sha1TryException ) 391 { 392 logger.debug( "SHA1 not found, trying MD5: " + sha1TryException.getMessage() ); 393 394 // if this IS NOT a ChecksumFailedException, it was a problem with transfer/read of the checksum 395 // file...we'll try again with the MD5 checksum. 396 try 397 { 398 verifyChecksum( md5ChecksumObserver, destination, temp, remotePath, ".md5", wagon ); 399 } 400 catch ( ChecksumFailedException e ) 401 { 402 // if we also fail to verify based on the MD5 checksum, and the checksum transfer/read 403 // succeeded, then we need to determine whether to retry or handle it as a failure. 404 if ( firstRun ) 405 { 406 retry = true; 407 } 408 else 409 { 410 handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() ); 411 } 412 } 413 catch ( ResourceDoesNotExistException md5TryException ) 414 { 415 // this was a failed transfer, and we don't want to retry. 416 handleChecksumFailure( checksumPolicy, "Error retrieving checksum file for " + remotePath, 417 md5TryException ); 418 } 419 } 420 421 // reinstate the download monitor... 422 if ( downloadMonitor != null ) 423 { 424 wagon.addTransferListener( downloadMonitor ); 425 } 426 } 427 428 // unset the firstRun flag, so we don't get caught in an infinite loop... 429 firstRun = false; 430 } 431 } 432 catch ( ConnectionException e ) 433 { 434 throw new TransferFailedException( "Connection failed: " + e.getMessage(), e ); 435 } 436 catch ( AuthenticationException e ) 437 { 438 throw new TransferFailedException( "Authentication failed: " + e.getMessage(), e ); 439 } 440 catch ( AuthorizationException e ) 441 { 442 throw new TransferFailedException( "Authorization failed: " + e.getMessage(), e ); 443 } 444 finally 445 { 446 // Remove remaining TransferListener instances (checksum handlers removed in above finally clause) 447 if ( downloadMonitor != null ) 448 { 449 wagon.removeTransferListener( downloadMonitor ); 450 } 451 452 disconnectWagon( wagon ); 453 454 releaseWagon( protocol, wagon ); 455 } 456 457 if ( downloaded ) 458 { 459 if ( !temp.exists() ) 460 { 461 throw new ResourceDoesNotExistException( "Downloaded file does not exist: " + temp ); 462 } 463 464 // The temporary file is named destination + ".tmp" and is done this way to ensure 465 // that the temporary file is in the same file system as the destination because the 466 // File.renameTo operation doesn't really work across file systems. 467 // So we will attempt to do a File.renameTo for efficiency and atomicity, if this fails 468 // then we will use a brute force copy and delete the temporary file. 469 470 if ( !temp.renameTo( destination ) ) 471 { 472 try 473 { 474 FileUtils.copyFile( temp, destination ); 475 476 temp.delete(); 477 } 478 catch ( IOException e ) 479 { 480 throw new TransferFailedException( "Error copying temporary file to the final destination: " 481 + e.getMessage(), e ); 482 } 483 } 484 } 485 } 486 487 // 488 // Publisher 489 // 490 public void putArtifact( File source, Artifact artifact, ArtifactRepository deploymentRepository, 491 TransferListener downloadMonitor ) 492 throws TransferFailedException 493 { 494 putRemoteFile( deploymentRepository, source, deploymentRepository.pathOf( artifact ), downloadMonitor ); 495 } 496 497 public void putArtifactMetadata( File source, ArtifactMetadata artifactMetadata, ArtifactRepository repository ) 498 throws TransferFailedException 499 { 500 logger.info( "Uploading " + artifactMetadata ); 501 putRemoteFile( repository, source, repository.pathOfRemoteRepositoryMetadata( artifactMetadata ), null ); 502 } 503 504 public void putRemoteFile( ArtifactRepository repository, File source, String remotePath, 505 TransferListener downloadMonitor ) 506 throws TransferFailedException 507 { 508 String protocol = repository.getProtocol(); 509 510 Wagon wagon; 511 try 512 { 513 wagon = getWagon( protocol ); 514 } 515 catch ( UnsupportedProtocolException e ) 516 { 517 throw new TransferFailedException( "Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e ); 518 } 519 520 if ( downloadMonitor != null ) 521 { 522 wagon.addTransferListener( downloadMonitor ); 523 } 524 525 Map<String, ChecksumObserver> checksums = new HashMap<String, ChecksumObserver>( 2 ); 526 527 Map<String, String> sums = new HashMap<String, String>( 2 ); 528 529 // TODO: configure these on the repository 530 for ( int i = 0; i < CHECKSUM_IDS.length; i++ ) 531 { 532 checksums.put( CHECKSUM_IDS[i], addChecksumObserver( wagon, CHECKSUM_ALGORITHMS[i] ) ); 533 } 534 535 List<File> temporaryFiles = new ArrayList<File>(); 536 537 try 538 { 539 try 540 { 541 connectWagon( wagon, repository ); 542 543 wagon.put( source, remotePath ); 544 } 545 finally 546 { 547 if ( downloadMonitor != null ) 548 { 549 wagon.removeTransferListener( downloadMonitor ); 550 } 551 } 552 553 // Pre-store the checksums as any future puts will overwrite them 554 for ( String extension : checksums.keySet() ) 555 { 556 ChecksumObserver observer = checksums.get( extension ); 557 sums.put( extension, observer.getActualChecksum() ); 558 } 559 560 // We do this in here so we can checksum the artifact metadata too, otherwise it could be metadata itself 561 for ( String extension : checksums.keySet() ) 562 { 563 // TODO: shouldn't need a file intermediatary - improve wagon to take a stream 564 File temp = File.createTempFile( "maven-artifact", null ); 565 temp.deleteOnExit(); 566 FileUtils.fileWrite( temp.getAbsolutePath(), "UTF-8", sums.get( extension ) ); 567 568 temporaryFiles.add( temp ); 569 wagon.put( temp, remotePath + "." + extension ); 570 } 571 } 572 catch ( ConnectionException e ) 573 { 574 throw new TransferFailedException( "Connection failed: " + e.getMessage(), e ); 575 } 576 catch ( AuthenticationException e ) 577 { 578 throw new TransferFailedException( "Authentication failed: " + e.getMessage(), e ); 579 } 580 catch ( AuthorizationException e ) 581 { 582 throw new TransferFailedException( "Authorization failed: " + e.getMessage(), e ); 583 } 584 catch ( ResourceDoesNotExistException e ) 585 { 586 throw new TransferFailedException( "Resource to deploy not found: " + e.getMessage(), e ); 587 } 588 catch ( IOException e ) 589 { 590 throw new TransferFailedException( "Error creating temporary file for deployment: " + e.getMessage(), e ); 591 } 592 finally 593 { 594 // MNG-4543 595 cleanupTemporaryFiles( temporaryFiles ); 596 597 // Remove every checksum listener 598 for ( String aCHECKSUM_IDS : CHECKSUM_IDS ) 599 { 600 TransferListener checksumListener = checksums.get( aCHECKSUM_IDS ); 601 if ( checksumListener != null ) 602 { 603 wagon.removeTransferListener( checksumListener ); 604 } 605 } 606 607 disconnectWagon( wagon ); 608 609 releaseWagon( protocol, wagon ); 610 } 611 } 612 613 private void cleanupTemporaryFiles( List<File> files ) 614 { 615 for ( File file : files ) 616 { 617 // really don't care if it failed here only log warning 618 try 619 { 620 file.delete(); 621 } 622 catch ( Exception e ) 623 { 624 logger.warn( "skip failed to delete temporary file : " + file.getAbsolutePath() + " , message " 625 + e.getMessage() ); 626 } 627 } 628 629 } 630 631 private ChecksumObserver addChecksumObserver( Wagon wagon, String algorithm ) 632 throws TransferFailedException 633 { 634 try 635 { 636 ChecksumObserver checksumObserver = new ChecksumObserver( algorithm ); 637 wagon.addTransferListener( checksumObserver ); 638 return checksumObserver; 639 } 640 catch ( NoSuchAlgorithmException e ) 641 { 642 throw new TransferFailedException( "Unable to add checksum for unsupported algorithm " + algorithm, e ); 643 } 644 } 645 646 private void handleChecksumFailure( String checksumPolicy, String message, Throwable cause ) 647 throws ChecksumFailedException 648 { 649 if ( ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL.equals( checksumPolicy ) ) 650 { 651 throw new ChecksumFailedException( message, cause ); 652 } 653 else if ( !ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE.equals( checksumPolicy ) ) 654 { 655 // warn if it is set to anything other than ignore 656 logger.warn( "*** CHECKSUM FAILED - " + message + " - IGNORING" ); 657 } 658 // otherwise it is ignore 659 } 660 661 private void verifyChecksum( ChecksumObserver checksumObserver, File destination, File tempDestination, 662 String remotePath, String checksumFileExtension, Wagon wagon ) 663 throws ResourceDoesNotExistException, TransferFailedException, AuthorizationException 664 { 665 try 666 { 667 // grab it first, because it's about to change... 668 String actualChecksum = checksumObserver.getActualChecksum(); 669 670 File tempChecksumFile = new File( tempDestination + checksumFileExtension + ".tmp" ); 671 tempChecksumFile.deleteOnExit(); 672 wagon.get( remotePath + checksumFileExtension, tempChecksumFile ); 673 674 String expectedChecksum = FileUtils.fileRead( tempChecksumFile, "UTF-8" ); 675 676 // remove whitespaces at the end 677 expectedChecksum = expectedChecksum.trim(); 678 679 // check for 'ALGO (name) = CHECKSUM' like used by openssl 680 if ( expectedChecksum.regionMatches( true, 0, "MD", 0, 2 ) 681 || expectedChecksum.regionMatches( true, 0, "SHA", 0, 3 ) ) 682 { 683 int lastSpacePos = expectedChecksum.lastIndexOf( ' ' ); 684 expectedChecksum = expectedChecksum.substring( lastSpacePos + 1 ); 685 } 686 else 687 { 688 // remove everything after the first space (if available) 689 int spacePos = expectedChecksum.indexOf( ' ' ); 690 691 if ( spacePos != -1 ) 692 { 693 expectedChecksum = expectedChecksum.substring( 0, spacePos ); 694 } 695 } 696 if ( expectedChecksum.equalsIgnoreCase( actualChecksum ) ) 697 { 698 File checksumFile = new File( destination + checksumFileExtension ); 699 if ( checksumFile.exists() ) 700 { 701 checksumFile.delete(); 702 } 703 FileUtils.copyFile( tempChecksumFile, checksumFile ); 704 tempChecksumFile.delete(); 705 } 706 else 707 { 708 throw new ChecksumFailedException( "Checksum failed on download: local = '" + actualChecksum 709 + "'; remote = '" + expectedChecksum + "'" ); 710 } 711 } 712 catch ( IOException e ) 713 { 714 throw new ChecksumFailedException( "Invalid checksum file", e ); 715 } 716 } 717 718 private void disconnectWagon( Wagon wagon ) 719 { 720 try 721 { 722 wagon.disconnect(); 723 } 724 catch ( ConnectionException e ) 725 { 726 logger.error( "Problem disconnecting from wagon - ignoring: " + e.getMessage() ); 727 } 728 } 729 730 private void releaseWagon( String protocol, Wagon wagon ) 731 { 732 try 733 { 734 container.release( wagon ); 735 } 736 catch ( ComponentLifecycleException e ) 737 { 738 logger.error( "Problem releasing wagon - ignoring: " + e.getMessage() ); 739 logger.debug( "", e ); 740 } 741 } 742 743 @Deprecated 744 public Wagon getWagon( Repository repository ) 745 throws UnsupportedProtocolException 746 { 747 return getWagon( repository.getProtocol() ); 748 } 749 750 @Deprecated 751 public Wagon getWagon( String protocol ) 752 throws UnsupportedProtocolException 753 { 754 if ( protocol == null ) 755 { 756 throw new UnsupportedProtocolException( "Unspecified protocol" ); 757 } 758 759 String hint = protocol.toLowerCase( java.util.Locale.ENGLISH ); 760 761 Wagon wagon; 762 try 763 { 764 wagon = container.lookup( Wagon.class, hint ); 765 } 766 catch ( ComponentLookupException e ) 767 { 768 throw new UnsupportedProtocolException( "Cannot find wagon which supports the requested protocol: " 769 + protocol, e ); 770 } 771 772 return wagon; 773 } 774 775 }