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