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 if ( !temp.delete() ) 509 { 510 temp.deleteOnExit(); 511 } 512 } 513 catch ( IOException e ) 514 { 515 throw new TransferFailedException( "Error copying temporary file to the final destination: " 516 + e.getMessage(), e ); 517 } 518 } 519 } 520 } 521 522 // 523 // Publisher 524 // 525 public void putArtifact( File source, Artifact artifact, ArtifactRepository deploymentRepository, 526 TransferListener downloadMonitor ) 527 throws TransferFailedException 528 { 529 putRemoteFile( deploymentRepository, source, deploymentRepository.pathOf( artifact ), downloadMonitor ); 530 } 531 532 public void putArtifactMetadata( File source, ArtifactMetadata artifactMetadata, ArtifactRepository repository ) 533 throws TransferFailedException 534 { 535 logger.info( "Uploading " + artifactMetadata ); 536 putRemoteFile( repository, source, repository.pathOfRemoteRepositoryMetadata( artifactMetadata ), null ); 537 } 538 539 public void putRemoteFile( ArtifactRepository repository, File source, String remotePath, 540 TransferListener downloadMonitor ) 541 throws TransferFailedException 542 { 543 String protocol = repository.getProtocol(); 544 545 Wagon wagon; 546 try 547 { 548 wagon = getWagon( protocol ); 549 } 550 catch ( UnsupportedProtocolException e ) 551 { 552 throw new TransferFailedException( "Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e ); 553 } 554 555 if ( downloadMonitor != null ) 556 { 557 wagon.addTransferListener( downloadMonitor ); 558 } 559 560 Map<String, ChecksumObserver> checksums = new HashMap<String, ChecksumObserver>( 2 ); 561 562 Map<String, String> sums = new HashMap<String, String>( 2 ); 563 564 // TODO: configure these on the repository 565 for ( int i = 0; i < CHECKSUM_IDS.length; i++ ) 566 { 567 checksums.put( CHECKSUM_IDS[i], addChecksumObserver( wagon, CHECKSUM_ALGORITHMS[i] ) ); 568 } 569 570 List<File> temporaryFiles = new ArrayList<File>(); 571 572 try 573 { 574 try 575 { 576 connectWagon( wagon, repository ); 577 578 wagon.put( source, remotePath ); 579 } 580 finally 581 { 582 if ( downloadMonitor != null ) 583 { 584 wagon.removeTransferListener( downloadMonitor ); 585 } 586 } 587 588 // Pre-store the checksums as any future puts will overwrite them 589 for ( String extension : checksums.keySet() ) 590 { 591 ChecksumObserver observer = checksums.get( extension ); 592 sums.put( extension, observer.getActualChecksum() ); 593 } 594 595 // We do this in here so we can checksum the artifact metadata too, otherwise it could be metadata itself 596 for ( String extension : checksums.keySet() ) 597 { 598 // TODO: shouldn't need a file intermediatary - improve wagon to take a stream 599 File temp = File.createTempFile( "maven-artifact", null ); 600 temp.deleteOnExit(); 601 FileUtils.fileWrite( temp.getAbsolutePath(), "UTF-8", sums.get( extension ) ); 602 603 temporaryFiles.add( temp ); 604 wagon.put( temp, remotePath + "." + extension ); 605 } 606 } 607 catch ( ConnectionException e ) 608 { 609 throw new TransferFailedException( "Connection failed: " + e.getMessage(), e ); 610 } 611 catch ( AuthenticationException e ) 612 { 613 throw new TransferFailedException( "Authentication failed: " + e.getMessage(), e ); 614 } 615 catch ( AuthorizationException e ) 616 { 617 throw new TransferFailedException( "Authorization failed: " + e.getMessage(), e ); 618 } 619 catch ( ResourceDoesNotExistException e ) 620 { 621 throw new TransferFailedException( "Resource to deploy not found: " + e.getMessage(), e ); 622 } 623 catch ( IOException e ) 624 { 625 throw new TransferFailedException( "Error creating temporary file for deployment: " + e.getMessage(), e ); 626 } 627 finally 628 { 629 // MNG-4543 630 cleanupTemporaryFiles( temporaryFiles ); 631 632 // Remove every checksum listener 633 for ( String aCHECKSUM_IDS : CHECKSUM_IDS ) 634 { 635 TransferListener checksumListener = checksums.get( aCHECKSUM_IDS ); 636 if ( checksumListener != null ) 637 { 638 wagon.removeTransferListener( checksumListener ); 639 } 640 } 641 642 disconnectWagon( wagon ); 643 644 releaseWagon( protocol, wagon ); 645 } 646 } 647 648 private void cleanupTemporaryFiles( List<File> files ) 649 { 650 for ( File file : files ) 651 { 652 // really don't care if it failed here only log warning 653 if ( !file.delete() ) 654 { 655 logger.warn( "skip failed to delete temporary file : " + file.getAbsolutePath() ); 656 file.deleteOnExit(); 657 } 658 } 659 660 } 661 662 private ChecksumObserver addChecksumObserver( Wagon wagon, String algorithm ) 663 throws TransferFailedException 664 { 665 try 666 { 667 ChecksumObserver checksumObserver = new ChecksumObserver( algorithm ); 668 wagon.addTransferListener( checksumObserver ); 669 return checksumObserver; 670 } 671 catch ( NoSuchAlgorithmException e ) 672 { 673 throw new TransferFailedException( "Unable to add checksum for unsupported algorithm " + algorithm, e ); 674 } 675 } 676 677 private void handleChecksumFailure( String checksumPolicy, String message, Throwable cause ) 678 throws ChecksumFailedException 679 { 680 if ( ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL.equals( checksumPolicy ) ) 681 { 682 throw new ChecksumFailedException( message, cause ); 683 } 684 else if ( !ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE.equals( checksumPolicy ) ) 685 { 686 // warn if it is set to anything other than ignore 687 logger.warn( "*** CHECKSUM FAILED - " + message + " - IGNORING" ); 688 } 689 // otherwise it is ignore 690 } 691 692 private void verifyChecksum( ChecksumObserver checksumObserver, File destination, File tempDestination, 693 String remotePath, String checksumFileExtension, Wagon wagon ) 694 throws ResourceDoesNotExistException, TransferFailedException, AuthorizationException 695 { 696 try 697 { 698 // grab it first, because it's about to change... 699 String actualChecksum = checksumObserver.getActualChecksum(); 700 701 File tempChecksumFile = new File( tempDestination + checksumFileExtension + ".tmp" ); 702 tempChecksumFile.deleteOnExit(); 703 wagon.get( remotePath + checksumFileExtension, tempChecksumFile ); 704 705 String expectedChecksum = FileUtils.fileRead( tempChecksumFile, "UTF-8" ); 706 707 // remove whitespaces at the end 708 expectedChecksum = expectedChecksum.trim(); 709 710 // check for 'ALGO (name) = CHECKSUM' like used by openssl 711 if ( expectedChecksum.regionMatches( true, 0, "MD", 0, 2 ) 712 || expectedChecksum.regionMatches( true, 0, "SHA", 0, 3 ) ) 713 { 714 int lastSpacePos = expectedChecksum.lastIndexOf( ' ' ); 715 expectedChecksum = expectedChecksum.substring( lastSpacePos + 1 ); 716 } 717 else 718 { 719 // remove everything after the first space (if available) 720 int spacePos = expectedChecksum.indexOf( ' ' ); 721 722 if ( spacePos != -1 ) 723 { 724 expectedChecksum = expectedChecksum.substring( 0, spacePos ); 725 } 726 } 727 if ( expectedChecksum.equalsIgnoreCase( actualChecksum ) ) 728 { 729 File checksumFile = new File( destination + checksumFileExtension ); 730 if ( checksumFile.exists() ) 731 { 732 checksumFile.delete(); // ignore if failed as we will overwrite 733 } 734 FileUtils.copyFile( tempChecksumFile, checksumFile ); 735 if ( !tempChecksumFile.delete() ) 736 { 737 tempChecksumFile.deleteOnExit(); 738 } 739 } 740 else 741 { 742 throw new ChecksumFailedException( "Checksum failed on download: local = '" + actualChecksum 743 + "'; remote = '" + expectedChecksum + "'" ); 744 } 745 } 746 catch ( IOException e ) 747 { 748 throw new ChecksumFailedException( "Invalid checksum file", e ); 749 } 750 } 751 752 private void disconnectWagon( Wagon wagon ) 753 { 754 try 755 { 756 wagon.disconnect(); 757 } 758 catch ( ConnectionException e ) 759 { 760 logger.error( "Problem disconnecting from wagon - ignoring: " + e.getMessage() ); 761 } 762 } 763 764 private void releaseWagon( String protocol, Wagon wagon ) 765 { 766 try 767 { 768 container.release( wagon ); 769 } 770 catch ( ComponentLifecycleException e ) 771 { 772 logger.error( "Problem releasing wagon - ignoring: " + e.getMessage() ); 773 logger.debug( "", e ); 774 } 775 } 776 777 @Deprecated 778 public Wagon getWagon( Repository repository ) 779 throws UnsupportedProtocolException 780 { 781 return getWagon( repository.getProtocol() ); 782 } 783 784 @Deprecated 785 public Wagon getWagon( String protocol ) 786 throws UnsupportedProtocolException 787 { 788 if ( protocol == null ) 789 { 790 throw new UnsupportedProtocolException( "Unspecified protocol" ); 791 } 792 793 String hint = protocol.toLowerCase( java.util.Locale.ENGLISH ); 794 795 Wagon wagon; 796 try 797 { 798 wagon = container.lookup( Wagon.class, hint ); 799 } 800 catch ( ComponentLookupException e ) 801 { 802 throw new UnsupportedProtocolException( "Cannot find wagon which supports the requested protocol: " 803 + protocol, e ); 804 } 805 806 return wagon; 807 } 808 809}