From 83c9eadb09e28f38f3e619d9b902cb66f3e3f94c Mon Sep 17 00:00:00 2001 From: Brett Leslie Porter Date: Tue, 7 Feb 2006 04:52:06 +0000 Subject: [PATCH] [MNG-1908] force an update check if there are legacy snapshots within the updatePolicy window git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@375485 13f79535-47bb-0310-9956-ffa450edef68 --- .../artifact/manager/DefaultWagonManager.java | 175 ++++++++++-------- .../resolver/DefaultArtifactResolver.java | 34 +++- 2 files changed, 129 insertions(+), 80 deletions(-) diff --git a/maven-artifact-manager/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java b/maven-artifact-manager/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java index d166e8d129..c3991cdf8a 100644 --- a/maven-artifact-manager/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java +++ b/maven-artifact-manager/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java @@ -73,7 +73,7 @@ public class DefaultWagonManager private Map serverPermissionsMap = new HashMap(); private Map mirrors = new HashMap(); - + private Map serverConfigurationMap = new HashMap(); private TransferListener downloadMonitor; @@ -128,14 +128,14 @@ public class DefaultWagonManager try { wagon = getWagon( protocol ); - + configureWagon( wagon, repository ); } catch ( UnsupportedProtocolException e ) { throw new TransferFailedException( "Unsupported Protocol: '" + protocol + "': " + e.getMessage(), e ); } - + if ( downloadMonitor != null ) { wagon.addTransferListener( downloadMonitor ); @@ -349,6 +349,8 @@ public class DefaultWagonManager File temp = new File( destination + ".tmp" ); temp.deleteOnExit(); + boolean downloaded = false; + try { wagon.connect( new Repository( repository.getId(), repository.getUrl() ), @@ -366,51 +368,38 @@ public class DefaultWagonManager retry = false; // This should take care of creating destination directory now on - wagon.get( remotePath, temp ); - - // keep the checksum files from showing up on the download monitor... - if ( downloadMonitor != null ) + if ( destination.exists() ) { - wagon.removeTransferListener( downloadMonitor ); + downloaded = wagon.getIfNewer( remotePath, temp, destination.lastModified() ); + } + else + { + wagon.get( remotePath, temp ); + downloaded = true; } - // try to verify the SHA-1 checksum for this file. - try + if ( downloaded ) { - verifyChecksum( sha1ChecksumObserver, destination, temp, remotePath, ".sha1", wagon ); - } - catch ( ChecksumFailedException e ) - { - // if we catch a ChecksumFailedException, it means the transfer/read succeeded, but the checksum - // doesn't match. This could be a problem with the server (ibiblio HTTP-200 error page), so we'll - // try this up to two times. On the second try, we'll handle it as a bona-fide error, based on the - // repository's checksum checking policy. - if ( firstRun ) + // keep the checksum files from showing up on the download monitor... + if ( downloadMonitor != null ) { - getLogger().warn( "*** CHECKSUM FAILED - " + e.getMessage() + " - RETRYING" ); - retry = true; + wagon.removeTransferListener( downloadMonitor ); } - else - { - handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() ); - } - } - catch ( ResourceDoesNotExistException sha1TryException ) - { - getLogger().debug( "SHA1 not found, trying MD5", sha1TryException ); - // if this IS NOT a ChecksumFailedException, it was a problem with transfer/read of the checksum - // file...we'll try again with the MD5 checksum. + // try to verify the SHA-1 checksum for this file. try { - verifyChecksum( md5ChecksumObserver, destination, temp, remotePath, ".md5", wagon ); + verifyChecksum( sha1ChecksumObserver, destination, temp, remotePath, ".sha1", wagon ); } catch ( ChecksumFailedException e ) { - // if we also fail to verify based on the MD5 checksum, and the checksum transfer/read - // succeeded, then we need to determine whether to retry or handle it as a failure. + // if we catch a ChecksumFailedException, it means the transfer/read succeeded, but the checksum + // doesn't match. This could be a problem with the server (ibiblio HTTP-200 error page), so we'll + // try this up to two times. On the second try, we'll handle it as a bona-fide error, based on the + // repository's checksum checking policy. if ( firstRun ) { + getLogger().warn( "*** CHECKSUM FAILED - " + e.getMessage() + " - RETRYING" ); retry = true; } else @@ -418,18 +407,42 @@ public class DefaultWagonManager handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() ); } } - catch ( ResourceDoesNotExistException md5TryException ) + catch ( ResourceDoesNotExistException sha1TryException ) { - // this was a failed transfer, and we don't want to retry. - handleChecksumFailure( checksumPolicy, "Error retrieving checksum file for " + remotePath, - md5TryException ); - } - } + getLogger().debug( "SHA1 not found, trying MD5", sha1TryException ); - // reinstate the download monitor... - if ( downloadMonitor != null ) - { - wagon.addTransferListener( downloadMonitor ); + // if this IS NOT a ChecksumFailedException, it was a problem with transfer/read of the checksum + // file...we'll try again with the MD5 checksum. + try + { + verifyChecksum( md5ChecksumObserver, destination, temp, remotePath, ".md5", wagon ); + } + catch ( ChecksumFailedException e ) + { + // if we also fail to verify based on the MD5 checksum, and the checksum transfer/read + // succeeded, then we need to determine whether to retry or handle it as a failure. + if ( firstRun ) + { + retry = true; + } + else + { + handleChecksumFailure( checksumPolicy, e.getMessage(), e.getCause() ); + } + } + catch ( ResourceDoesNotExistException md5TryException ) + { + // this was a failed transfer, and we don't want to retry. + handleChecksumFailure( checksumPolicy, "Error retrieving checksum file for " + remotePath, + md5TryException ); + } + } + + // reinstate the download monitor... + if ( downloadMonitor != null ) + { + wagon.addTransferListener( downloadMonitor ); + } } // unset the firstRun flag, so we don't get caught in an infinite loop... @@ -455,29 +468,32 @@ public class DefaultWagonManager releaseWagon( wagon ); } - if ( !temp.exists() ) + if ( downloaded ) { - throw new ResourceDoesNotExistException( "Downloaded file does not exist: " + temp ); - } - - // The temporary file is named destination + ".tmp" and is done this way to ensure - // that the temporary file is in the same file system as the destination because the - // File.renameTo operation doesn't really work across file systems. - // So we will attempt to do a File.renameTo for efficiency and atomicity, if this fails - // then we will use a brute force copy and delete the temporary file. - - if ( !temp.renameTo( destination ) ) - { - try + if ( !temp.exists() ) { - FileUtils.copyFile( temp, destination ); - - temp.delete(); + throw new ResourceDoesNotExistException( "Downloaded file does not exist: " + temp ); } - catch ( IOException e ) + + // The temporary file is named destination + ".tmp" and is done this way to ensure + // that the temporary file is in the same file system as the destination because the + // File.renameTo operation doesn't really work across file systems. + // So we will attempt to do a File.renameTo for efficiency and atomicity, if this fails + // then we will use a brute force copy and delete the temporary file. + + if ( !temp.renameTo( destination ) ) { - throw new TransferFailedException( - "Error copying temporary file to the final destination: " + e.getMessage(), e ); + try + { + FileUtils.copyFile( temp, destination ); + + temp.delete(); + } + catch ( IOException e ) + { + throw new TransferFailedException( + "Error copying temporary file to the final destination: " + e.getMessage(), e ); + } } } } @@ -506,8 +522,8 @@ public class DefaultWagonManager // otherwise it is ignore } - private void verifyChecksum( ChecksumObserver checksumObserver, File destination, File tempDestination, String remotePath, - String checksumFileExtension, Wagon wagon ) + private void verifyChecksum( ChecksumObserver checksumObserver, File destination, File tempDestination, + String remotePath, String checksumFileExtension, Wagon wagon ) throws ResourceDoesNotExistException, TransferFailedException, AuthorizationException { try @@ -543,7 +559,10 @@ public class DefaultWagonManager if ( expectedChecksum.equals( actualChecksum ) ) { File checksumFile = new File( destination + checksumFileExtension ); - if ( checksumFile.exists() ) checksumFile.delete(); + if ( checksumFile.exists() ) + { + checksumFile.delete(); + } FileUtils.copyFile( tempChecksumFile, checksumFile ); } else @@ -600,13 +619,13 @@ public class DefaultWagonManager /** * Set the proxy used for a particular protocol. * - * @param protocol the protocol (required) - * @param host the proxy host name (required) - * @param port the proxy port (required) - * @param username the username for the proxy, or null if there is none - * @param password the password for the proxy, or null if there is none + * @param protocol the protocol (required) + * @param host the proxy host name (required) + * @param port the proxy port (required) + * @param username the username for the proxy, or null if there is none + * @param password the password for the proxy, or null if there is none * @param nonProxyHosts the set of hosts not to use the proxy for. Follows Java system - * property format: *.foo.com|localhost. + * property format: *.foo.com|localhost. * @todo [BP] would be nice to configure this via plexus in some way */ public void addProxy( String protocol, String host, int port, String username, String password, @@ -698,12 +717,12 @@ public class DefaultWagonManager { this.interactive = interactive; } - + /** * Applies the server configuration to the wagon - * - * @param wagon the wagon to configure + * + * @param wagon the wagon to configure * @param repository the repository that has the configuration * @throws WagonConfigurationException wraps any error given during configuration of the wagon instance */ @@ -724,7 +743,9 @@ public class DefaultWagonManager } catch ( final ComponentLookupException e ) { - throw new WagonConfigurationException( repositoryId, "Unable to lookup wagon configurator. Wagon configuration cannot be applied.", e ); + throw new WagonConfigurationException( repositoryId, + "Unable to lookup wagon configurator. Wagon configuration cannot be applied.", + e ); } catch ( ComponentConfigurationException e ) { @@ -747,7 +768,7 @@ public class DefaultWagonManager } } } - + public void addConfiguration( String repositoryId, Xpp3Dom configuration ) { diff --git a/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java b/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java index b8e229fdfc..e2f881f791 100644 --- a/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java +++ b/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java @@ -21,6 +21,7 @@ import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.manager.WagonManager; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.transform.ArtifactTransformationManager; import org.apache.maven.wagon.ResourceDoesNotExistException; @@ -32,6 +33,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -104,6 +106,32 @@ public class DefaultArtifactResolver transformationManager.transformForResolve( artifact, remoteRepositories, localRepository ); File destination = artifact.getFile(); + List repositories = remoteRepositories; + + // TODO: would prefer the snapshot transformation took care of this. Maybe we need a "shouldresolve" flag. + if ( artifact.isSnapshot() && artifact.getBaseVersion().equals( artifact.getVersion() ) && + destination.exists() ) + { + Date comparisonDate = new Date( destination.lastModified() ); + + // cull to list of repositories that would like an update + repositories = new ArrayList( remoteRepositories ); + for ( Iterator i = repositories.iterator(); i.hasNext(); ) + { + ArtifactRepository repository = (ArtifactRepository) i.next(); + ArtifactRepositoryPolicy policy = repository.getSnapshots(); + if ( !policy.isEnabled() || !policy.checkOutOfDate( comparisonDate ) ) + { + i.remove(); + } + } + + if ( !repositories.isEmpty() ) + { + // someone wants to check for updates + force = true; + } + } boolean resolved = false; if ( !destination.exists() || force ) { @@ -121,7 +149,7 @@ public class DefaultArtifactResolver } else { - wagonManager.getArtifact( artifact, remoteRepositories ); + wagonManager.getArtifact( artifact, repositories ); } if ( !artifact.isResolved() ) @@ -238,11 +266,11 @@ public class DefaultArtifactResolver missingArtifacts.add( node.getArtifact() ); } } - + if ( missingArtifacts.size() > 0 ) { String message = "required artifacts missing:\n"; - for( Iterator i=missingArtifacts.iterator(); i.hasNext(); ) + for ( Iterator i = missingArtifacts.iterator(); i.hasNext(); ) { Artifact missingArtifact = (Artifact) i.next(); message += " " + missingArtifact.getId() + "\n";